1

I am writing an if-then-else statement using awk in a bash script.

What I would like to do is identify lines with col 1 values not matching a particular string (rs or chr) and append a prefix (chr) to the col 1 values for those identified lines. All lines with the matched string should print as they were - no appending.

My line of code so far is:

awk '{if (! ($1 ~ /rs/ || $1 ~ /chr/)) {($1 == "chr"$1); print $0}}; else {print $0}' filename > newfilename

I keep on receiving syntax error messages with this code.

I can perform the identification and the appending successfully on their own but am having problems combining them into one command.

  • check where you close that second curly bracket: '{ if ( this is given) { do this } else { do that } }' – Fiximan Aug 24 '15 at 15:01
3

Here is your code, expanded for viewability:

awk '
    {
        if (! ($1 ~ /rs/ || $1 ~ /chr/) )
        {
            ($1 == "chr"$1);
            print $0}
        };
        else
        { print $0 }
' filename > newfilename

There are a number of issues with this that spring to mind

  1. You're using an equality comparison instead of assignment to try and add the chr prefix
  2. You have put what should be an assignment in brackets
  3. There is an extraneous } after the first print $0
  4. There should be no semicolon before the else part
  5. You're missing the final close } after the code

Here is a fixed version, still expanded:

awk '
    {
        if (! ($1 ~ /rs/ || $1 ~ /chr/) )
        {
            $1 = "chr"$1;
            print $0
        }
        else
        { print $0 }
    }
' filename > newfilename

And then we can see a simple optimisation to move the repeated print $0 outside your condition:

awk '
    {
        if (! ($1 ~ /rs/ || $1 ~ /chr/) )
        {
            $1 = "chr"$1
        }
        print $0
    }
' filename > newfilename

Since this is basically a simple "condition → amend" you can actually use awk's standard structure to simplify this further. Here we have two awk statements, processed sequentially for every line of your input file. The first line prefixes chr as necessary. The second prints every line.

awk '
    (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr"$1 }
    1
' filename > newfilename
1

Using this line seems to work perfectly:

awk '!($1 ~ /rs/ || /chr/) {$1="chr"$1}1'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.