Вложенная петля с двумя массивами - PullRequest
0 голосов
/ 29 августа 2011

У меня есть два набора массивов с переменным числом элементов, например:

chain = (BC)

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, но только если эти строки также соответствуют элементу из массива цепей под номером cloumn5-е:

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 Ответ

1 голос
/ 29 августа 2011

Вы можете добавить &&, измените эту строку:

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

На

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

Обновление: в скрипте слишком много ошибок, я исправил его исейчас работает.Я предлагаю вам сначала прочитать синтаксис цикла for в руководстве по bash.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...