带有两个数组的嵌套循环

时间:2011-08-29 10:12:32

标签: arrays bash loops nested

我有两组具有可变数量元素的数组,例如:

chain =(B C)

hresname =(BMA MAN NAG NDG)

我正在解析许多文件,这些文件可能包含给定位置的数组链中的元素,而数组hresname的元素位于不同的位置(在两种情况下,位置始终是固定的)。这是数据样本:

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  

首先,我需要复制以ATOM开头的行,其第5列与数组链的每个元素匹配,以分隔文件:

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

这很好用(慢但确定)。评论版和未评论版都可以使用。

接下来我想要复制以HETATM开头并且第4列与hresname元素匹配的行,但前提是这些行也匹配元素来自第5列的链数组:

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

然而,这不起作用。我反复收到一个错误:

line 66: [: too many arguments

第66行是:

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

令我困惑的是,即使我将循环限制为包含单个元素的链数组,也会发生错误。

根据其他StackOverflow问题,应该完全可以在bash中执行此操作。知道问题可能是什么?

1 个答案:

答案 0 :(得分:1)

您要添加&&,请更改此行:

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

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

更新: 你在脚本中有太多错误,我修复了它,现在它正在运行。我建议你首先阅读bash手册中的for循环语法。

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