If condition matches append to line

Viewed 63

I have a tab delim file

NC_044998.1     4015    0       TT      2       GG      0       TT      0       TT      0       TT      
NC_044998.1     4015    0       TT      0       TT      0       TT      2       GG      0       TT      
NC_044998.1     4016    0       TT      0       TT      0       TT      0       TT      0       TT      
NC_044998.1     4016    0       TT      0       TT      0       TT      0       TT      0       TT      
NC_044998.1     4017    2       CC      2       CC      2       CC      2       CC      2       CC      

I wanna add "fixed" to the lines where alternate cols $4,$6,$8,$10,$12 are the same, else add "var". So that the output is

NC_044998.1     4015    0       TT      2       GG      0       TT      0       TT      0       TT  var    
NC_044998.1     4015    0       TT      0       TT      0       TT      2       GG      0       TT  var   
NC_044998.1     4016    0       TT      0       TT      0       TT      0       TT      0       TT  fixed   
NC_044998.1     4016    0       TT      0       TT      0       TT      0       TT      0       TT  fixed    
NC_044998.1     4017    2       CC      2       CC      2       CC      2       CC      2       CC  fixed

I'm currently using this modification of an answer to a similar question I had posted.

awk -F '\t' '{for (i=6; i<=24; i+=2) if ($i == $4) print $0,"fixed"; else print $0,"var"}' 

But it doesn't it seems to be only looking at the first i in the loop.

2 Answers

You can tweak your attempt a bit like this:

awk -v fpos="4 6 8 10 12" 'BEGIN {
   FS=OFS="\t"
   split(fpos, flds, / /)
}
{
   for (i in flds)
      if ( $(flds[i]) != $(flds[1]) ) {
         print $0, "var"
         next
      }
   print $0, "fixed"
}' file
NC_044998.1 4015    0   TT  2   GG  0   TT  0   TT  0   TT var
NC_044998.1 4015    0   TT  0   TT  0   TT  2   GG  0   TT var
NC_044998.1 4016    0   TT  0   TT  0   TT  0   TT  0   TT fixed
NC_044998.1 4016    0   TT  0   TT  0   TT  0   TT  0   TT fixed
NC_044998.1 4017    2   CC  2   CC  2   CC  2   CC  2   CC fixed

If filed positions always increment by 2 then you may use this awk:

awk 'BEGIN {
   FS = OFS = "\t"
}
{
   for (i=6; i<=12; i+=2)
      if ($i != $4) {
         print $0, "var"
         next
      }
      print $0, "fixed"
}' file

Here's one using conditional operator in the print:

$ awk '
BEGIN {
    FS=OFS="\t"
}
{
    print $0,($4==$6 && $6==$8 && $8==$10 && $10==$12?"fixed":"var")
}' file

Output:

NC_044998.1     4015    0       TT      2       GG      0       TT      0       TT      0       TT      var
NC_044998.1     4015    0       TT      0       TT      0       TT      2       GG      0       TT      var
NC_044998.1     4016    0       TT      0       TT      0       TT      0       TT      0       TT      fixed
NC_044998.1     4016    0       TT      0       TT      0       TT      0       TT      0       TT      fixed
NC_044998.1     4017    2       CC      2       CC      2       CC      2       CC      2       CC      fixed

Your method would work like this:

$ awk -F '\t' '{
    for(i=4;i<12;i+=2)       # loop from 4 to ... not 12
        if($i!=$(i+2)) {     # if i and next meaningful field do not equal
            print $0,"var"   # output var
            next             # and jump to next record
        } 
    print $0,"fixed"         # if loop is passed without next, its fixed
}' file
Related