Home > Net >  Awk if else with conditions
Awk if else with conditions

Time:05-09

I am trying to make a script (and a loop) to extract matching lines to print them into a new file. There are 2 conditions: 1st is that I need to print the value of the 2nd and 4th columns of the map file if the 2nd column of the map file matches with the 4th column of the test file. The 2nd condition is that when there is no match, I want to print the value in the 2nd column of the test file and a zero in the second column.

My test file is made this way:

8   8:190568    0   190568  
8   8:194947    0   194947  
8   8:197042    0   197042  
8   8:212894    0   212894  

My map file is made this way:

8   190568  0.431475    0.009489
8   194947  0.434984    0.009707
8   19056880    0.395066    112.871160
8   101908687   0.643861    112.872348

1st attempt:

for chr in {21..22}; 
do
awk 'NR==FNR{a[$2]; next} {if ($4 in a) print $2, $4 in a; else print $2, $4 == "0"}' map_chr$chr.txt test_chr$chr.bim > position.$chr;
done

Result:

8:190568 1
8:194947 1
8:197042 0
8:212894 0

My second script is:

for chr in {21..22}; do
    awk 'NR == FNR {   a[$4]; next }
      $4 in a { print a[$2], $4;   found[$2] }
      END { for(k in a) if (!found[k]) print a[k], 0 }' \
         "test_chr$chr.bim"  "map_chr$chr.txt" >> "position.$chr"
done

And the result is:

1 0
1 0
1 0
1 0

The result I need is:

8:190568 0.009489
8:194947 0.009707
8:197042 0
8:212894 0

CodePudding user response:

This awk should work for you:

awk 'FNR==NR {map[$2]=$4; next} {print $4, map[$4] 0}' mapfile testfile

190568 0.009489
194947 0.009707
197042 0
212894 0

This awk command processes mapfile first and stores $2 as key with $4 as a value in an associative array named as map. Later when it processes testfile in 2nd block we print $4 from 2nd file with the stored value in map using key as $4. We add 0 in stored value to make sure that we get 0 when $4 is not present in map.

  • Related