1

I am parsing a number of files and copying the lines matching two conditions to a new file. The script behaves differently depending on the size of the array:

while read pdb ; do
# for c in "${chain[@]}" ; do
for ((c=0; c<${#chain[@]}; c++)) ; do
if [ ${#chain[@]} -eq 1 ] && [ "$(echo "$pdb" | cut -c1-4)" == "ATOM" ] && [ "$(echo "$pdb" | cut -c22-23)" == "${chain[$c]}" ] ; then
echo "$pdb" >> ../../properpdb/${pdbid}_${chain[$c]}.pdb
fi
done
done < ${pdbid}.pdb

This works, but only if I remove the last condition (the one referring to a particular array element). I have tried many different syntaxes (double square brackets, using ${c} rather than ${chain[$c]}, etc.) to no avail.

This is ${pdbid}.pdb

ATOM     13  CA  SER A   9     107.761  75.138  27.465  1.00 24.92           C  
ATOM     14  C   SER A   9     107.081  73.915  26.851  1.00 21.25           C  
ATOM     15  O   SER A   9     105.984  73.987  26.313  1.00 24.75           O  
ATOM     16  CB  SER A   9     107.956  76.218  26.399  1.00 30.66           C  

This is one of the arrays:

chain=(A)

Debug:

+ read pdb
+ for c in '"${chain[@]}"'
+ '[' 1 -eq 1 ']'
++ echo 'ATOM   1916  CZ3 TRP B  43     -15.691  19.837  49.406  1.00 12.45           C'
++ cut -c1-4
+ '[' ATOM == ATOM ']'
++ echo 'ATOM   1916  CZ3 TRP B  43     -15.691  19.837  49.406  1.00 12.45           C'
++ cut -c22-23
+ [[ A == B  ]]
+ read pdb

Everything seems to be right except that the last condition is not surrounded by single quotes. There is no output even if A == A. If I remove that condition, it works.

3
  • Can you provide a piece of ${pdbid}.pdb so we can try it out? Commented Aug 29, 2011 at 8:32
  • set -vx or change shebang to /bin/bash -x to turn on debugging. Check output to see that everything is expanded as intended (probably the quoting)... See bash debugging Commented Aug 29, 2011 at 8:34
  • Description updated with input samples and debug info. Commented Aug 29, 2011 at 8:48

1 Answer 1

1

The problem is you cut two characters in the test expression, it should be:

if [ ${#chain[@]} -eq 1 ] && \
   [ $(echo "$pdb" | cut -c1-4) == "ATOM" ] && \
   [ $(echo "$pdb" | cut -c22-22) == "${chain[$c]}" ]; then     
    echo "$pdb" >> ${pdbid}_${chain[$c]}.pdb
fi

You should use cut -c22-22 rather than -c22-23. I removed the double quotes around the command substitution so it will also remove white spaces for you.

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

3 Comments

I don't think that's true. The parentheses will start a new subshell and a new "quoting scope". As an example, try this with and without outer quotes: echo "$(echo "foo bar")" (make sure you use multiple spaces between foo and bar: markdown won't let me do it here)
@glenn you are probably right. The strange thing is that if double quote is used around command substitution, the solution won't work. Maybe it's a bug from bash. The problematic line is [ "$(echo "$pdb" | cut -c22-23)" == "${chain[$c]}" ]
however, the reason it works is not because you can't mix quotes (you can), but the side-effect of not quoting is to drop any leading spaces, and most likely the value of ${chain[0]} does not have leading spaces.

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.