0
#CHROM  POS     T1      T10     T11     T12     T13     T2      T3      T4      T5      T6      T106    T107    T108    T109    T110    T112    T114    T116    T120    T122    T125    T128    T129    T130
Aradu.A01       300806  H       B       B       B       B       B       B       B       H       B       B       H       B       B       B       B       B       B       B       B       B       B       B
Aradu.A01       386907  A       A       A       A       A       A       A       A       A       A       A       A       H       A       A       A       A       A       H       A       A       A       A
Aradu.A01       463100  B       B       A       A       A       A       A       H       B       A       A       H       H       H       H       H       B       A       B       A       H       H       A
Aradu.A01       471639  A       A       A       A       H       A       A       H       A       A       H       A       A       A       A       A       H       A       A       A       H       A       A
Aradu.A01       644024  H       B       B       B       B       B       B       B       H       H       B       H       H       B       B       B       H       B       H       B       B       B       H
Aradu.A01       756331  H       H       H       H       H       H       H       H       B       B       B       H       H       H       H       H       B       H       H       H       B       B       B
Aradu.A01       768081  A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A
Aradu.A01       783066  A       A       H       A       H       H       A       A       A       A       H       A       H       A       A       A       A       A       A       H       A       A       H
Aradu.A01       812865  H       B       H       H       H       H       H       H       H       H       H       H       H       H       H       H       B       B       H       H       B       B       H
Aradu.A01       976731  A       H       A       H       H       A       H       H       A       H       H       A       H       H       A       A       H       A       H       A       A       A       H
Aradu.A01       1089311 A       H       H       H       H       A       A       A       H       A       H       B       A       H       H       H       H       H       A       A       H       H       H
Aradu.A01       1089991 A       A       A       H       A       A       H       A       A       H       A       A       A       A       H       A       A       A       A       A       A       A       H
Aradu.A01       1113781 H       H       H       H       H       H       H       A       H       H       H       H       H       H       A       H       H       A       H       A       H       H       H
Aradu.A01       1160441 B       B       B       B       B       B       H       B       H       B       B       B       B       B       H       B       B       B       B       B       B       B       B
Aradu.A01       1638873 B       H       B       B       H       B       B       B       B       B       B       B       H       H       H       B       B       B       B       B       H       B       B
Aradu.A01       1638907 B       H       B       B       H       B       B       B       H       B       B       B       H       H       H       B       B       B       B       B       H       B       B

Can anyone please help me with an awk code that can only get me the rows which have fields with "A" and "B" in it? The rows with
1) only "A" and "H",
2) only "B" and "H" are NOT to be considered.

Each must have both A and B. If H is also present with A and B then also the row should be considered. In summary, need to have only the rows with "A" and "B" and if "H" is there along with "A" and "B" then that row should also be considered:

NR>1  {for(i=3;i<=NF;i++)
        { if ( $i ~ "A" && $i ~ "B" && $1 ~ "H" ) ;
       } ## if ;
       ## for loop is done
       print ;

The above code returns the output file as the input file. }

  • So to clarify, you don't care if "H" appears or not? You want all rows that contain "A" and "B", regardless of whether there's also a "H" in them? – JigglyNaga Jan 6 '17 at 16:39
  • There could be a possibility that H is also present with A and B. The selection criteria should be that each row must have A and B fields but if it has H as well then consider that row. The rows which either only have A and H or only have B and H must not be considered. you are right! – gaurav agarwal Jan 6 '17 at 16:45
2

Your script has several problems:

  • It tests whether any field matches both "A" and "B", at the same time. As long as the fields are only a single character (so you can't get "AB", "BAA" etc.), this will never be true.
  • It's looking for H, when it doesn't matter whether or not H appears
  • It's looking for H in $1 (the first field), every time round the loop
  • The outcome of all of these tests makes no difference: the if test has no matching action. The print is always reached, for every line.

To track whether A and B are present in the same line (in different fields), you could use a variable for each:

NR>1  {
    #beginning of line - no As or Bs seen yet
    A=0
    B=0
    #looping over all fields except the first two
    #break as soon as both A and B found
    for(i=3; A*B == 0 && i<=NF; i++) {
        if ( $i ~ "A" ) A=1
        if ( $i ~ "B" ) B=1
   }
    #print line if A and B were found
    if (A && B) print
}
  • Small optimization: for (i = 3; A*B == 0 && i <= NF; ++i) – Kusalananda Jan 6 '17 at 17:12
0

Not an awk solution, but this grep seems to do the trick:

egrep '^Aradu\.[A-Z][0-9]{2}.*A.*B|^Aradu\.[A-Z][0-9]{2}.*B.*A' aradu
Aradu.A01       463100  B       B       A       A       A       A       A       H       B       A       A       H       H       H       H       H       B       A       B       A       H       H       A
Aradu.A01       1089311 A       H       H       H       H       A       A       A       H       A       H       B       A       H       H       H       H       H       A       A       H       H       H

Where aradu is your example file.

Edit, Breakdown of regex:
^Aradu\.[A-Z][0-9]{2} = Lines beginning with 'Aradu' followed by a literal '.' followed by any uppercase character, followed by any integer two times.
.*A.*B = Followed by any character, any number of times (.*), followed by literal 'A', followed by literal 'B'
| = Logical or.
(The same beginning of the expression until)
.*B.*A = Any character, repeated any number of times, followed by a literal 'B', followed by a literal 'A'.

grep doesn't have a && (logical and) operator, this is the closest (to my knowledge) you can come to search for a line with A && B || B && A.

  • Thanks maulinglawns! Could you please explain {2}.*A.B ? – gaurav agarwal Jan 6 '17 at 18:51
  • See my edit, I tried my best to explain the regular expression I used. – maulinglawns Jan 6 '17 at 19:06
  • 1
    You could use branches instead of duplicating the start-of-line match: ^Aradu\.[A-Z][0-9]{2}.*(A.*B|B.*A) – JigglyNaga Jan 7 '17 at 10:41
  • @JigglyNaga Yes, true. That would probably be better! – maulinglawns Jan 7 '17 at 14:05

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.