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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.