0

I am trying to make a script to check if the value snp (column $4 of the test file) is present in another file (map file). If so, print the value snp and the value distance taken from the map file (distance is the column $4 of the map file). If the snp value from the test file is not present in the map file, print the snp value but put a 0 (zero) in the second column as distance value.

The script is:

for chr in {1..22}; 
do
for snp in awk '{print $4}' test$chr.bim
i=$(grep $snp map$chr.txt | wc -l | awk '{print $1}')
if [[ $i == "0" ]]
then 
echo "$snp 0" >> position.$chr
else
distance=$(grep $snp map$chr.txt | awk '{print $4}')
echo "$snp $distance" >> position.$chr
fi
done
done

my map file is made like this:

Chromosome  Position(bp)    Rate(cM/Mb) Map(cM)
chr22   16051347    8.096992    0.000000
chr22   16052618    8.131520    0.010291
chr22   16053624    8.131967    0.018472

and so on..

my test file is made like this:

22  16051347    0   16051347    C   A
22  16052618    0   16052618    G   T
22  17306184    0   17306184    T   G

and so on..

I'm getting the following syntax errors:

position.sh: line 6: syntax error near unexpected token `i=$(grep $snp map$chr.txt | wc -l | awk '{print $1}')'
position.sh: line 6: `i=$(grep $snp map$chr.txt | wc -l | awk '{print $1}')' 

Any tip?

6
  • 1
    about test$chr.bim does this mean that name of your file is test"something"? If yes, try to rename the file. The word "test" has a special usage for bash. Commented Apr 22, 2022 at 10:32
  • Hello. No, my actual file has another name (Roma_test_chr$chr.bim). I wrote test only to make it simpler to explain in here Commented Apr 22, 2022 at 10:34
  • 1
    Please add a suitable shebang (#!/bin/bash) and then paste your script at shellcheck.net and try to implement the recommendations made there. Commented Apr 22, 2022 at 10:37
  • Yes, follow the advise of Cyrus. You have quite a lot of synthax errors , i.e missing semicolons ; Commented Apr 22, 2022 at 10:39
  • @GeorgeVasiliou That's not correct either; it will quote the output of Awk and regard it as a single value. Commented Apr 22, 2022 at 10:48

1 Answer 1

1

The attempt to use awk as the argument to for is basically a syntax error, and you have a number of syntax problems and inefficiencies here.

Try this:

for chr in {1..22}; do
    awk '{print $4}' "test$chr.bim" |
    while IFS="" read -r snp; do
        if ! grep -q "$snp" "map$chr.txt"; then
            echo "$snp 0"
        else
            awk -v snp="$snp" '
                $0 ~ snp { print snp, $4 }' "map$chr.txt"
        fi  >> "position.$chr"
    done
done

The entire thing could probably be further refactored to a single Awk script.

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

The correct for syntax for what I'm guessing you wanted would look like

for snp in $(awk '{print $4}' "test$chr.bim"); do

but this has other problems; see don't read lines with for

Sign up to request clarification or add additional context in comments.

4 Comments

@Gf.Ena don't use the first script, use the second (or something similar if it's not totally correct). The first one will be extremely slow and it's just not necessary to keep jumping in/out of awk and other tools. See why-is-using-a-shell-loop-to-process-text-considered-bad-practice
@EdMorton I've tried the second script but it only prints a column of 1 and a second column of 0, that'it. I'm trying to see what's wrong but so far no success
That would imply the 4th column of your map file is always 0s.
If you still need help, probably post a new question with a minimal reproducible example where you have a representative input which does not generate the desired output, and you explain how the actual output is different from what you want. (But do search for existing questions; how to perform different joins in Awk is a very common topic.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.