开发者

Nested loop with two arrays

开发者 https://www.devze.com 2023-03-31 05:22 出处:网络
I have two sets of arrays with a variable number of elements, for instance: chain=(B C) hresname=(BMA MAN NAG NDG)

I have two sets of arrays with a variable number of elements, for instance:

chain=(B C)

hresname=(BMA MAN NAG NDG)

I am parsing a number of files that may contain element开发者_运维问答s from the array chain at a given position and elements of the array hresname at a different position (position is always fixed in both cases). This is a sample of the data:

ATOM   5792  CB  MET D 213      49.385  -5.683 125.489  1.00142.66           C  
ATOM   5793  CG  MET D 213      50.834  -5.674 125.990  1.00154.50           C  
ATOM   5794  SD  MET D 213      51.530  -7.337 126.277  1.00164.73           S  
ATOM   5795  CE  MET D 213      52.854  -7.386 125.068  1.00169.73           C  
HETATM 5797  C1  NAG B 323      70.090  50.934 125.869  1.00 86.35           C  
HETATM 5798  C2  NAG B 323      69.687  52.074 126.879  1.00 95.95           C  
HETATM 5799  C3  NAG B 323      68.377  52.740 126.390  1.00 87.65           C  
HETATM 5800  C4  NAG B 323      68.598  53.314 125.014  1.00 83.97           C  

First I need to copy lines starting with ATOM whose 5th column matches each of the elements of the array chain to separate files:

while read pdb ; do

for c in "${chain[@]}" ; do
#if [ ${#chain[@]} -eq 1 ] && \
if [ $(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 well (slow but sure). Both the commented and the uncommented versions work.

Next I want to copy lines that start with HETATM and whose 4th column matches elements of the hresname but only if those lines also match an element form the chain array at cloumn number 5th:

while read pdb ; do

for c in "${chain[@]}" ; do
for h in "${hresname[@]}" ; do
if [ ${#chain[@]} -eq 1 ] && \
   [ $(echo "$pdb" | cut -c1-6) == "HETATM" ] && \
   [ $(echo "$pdb" | cut -c22-23) == "${chain[$c]}" ] \
   [ $(echo "$pdb" | cut -c18-20) == "${hresname[$h]}" ] ; then
echo "$pdb" >> ../../properpdb/${pdbid}_${chain[$c]}.pdb
fi
done
done

done < ${pdbid}.pdb

However, this does not work. I repeatedly receive an error:

line 66: [: too many arguments

Line 66 is:

   [ $(echo "$pdb" | cut -c22-23) == "${chain[$c]}" ] \

Which puzzles me because the error happens even if I restrict the loop to chain arrays containing a single element.

According to other StackOverflow questions, it should be perfectly possible to do this in bash. Any idea what the problem could be?


You for get to add &&, change this line:

[ $(echo "$pdb" | cut -c22-23) == "${chain[$c]}" ] \

To

[ $(echo "$pdb" | cut -c22-23) == "${chain[$c]}" ] &&\

Update: You have too many errors in the script, I fixed it and it's now working. I suggest you read the for loop syntax in the bash manual first.

chain=(B C)                                                                                                                                
hresname=(BMA MAN NAG NDG)
while read pdb ; do
    for c in ${chain[@]} ; do
        for h in ${hresname[@]} ; do
            if [ $(echo "$pdb" | cut -c1-6) == "HETATM" ] && \
               [ $(echo "$pdb" | cut -c22-23) == "$c" ] && \
               [ $(echo "$pdb" | cut -c18-20) == "$h" ] ; then
                echo "$pdb" >> ../../properpdb/${pdbid}_${chain[$c]}.pdb
            fi
        done
    done
done
0

精彩评论

暂无评论...
验证码 换一张
取 消