2011-08-29 36 views
1

我正在解析许多文件,并将符合两个条件的行复制到新文件中。该脚本行为有所取决于数组的大小:双循环内的Bash数组(while/for/if)

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 

这工作,但只有当我删除了最后一个条件(一指某个特定数组元素)。我尝试了许多不同的语法(双方括号,使用$ {c}而不是$ {chain [$ c]}等)无济于事。

这是$ {} 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 

这是阵列中的一个:

chain=(A) 

调试:

+ 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 

一切似乎除了该右侧最后一个条件不被单引号包围。即使A == A也没有输出。如果我删除了这个条件,它就会起作用。

+0

你能提供一块$ {pdbid} .pdb,所以我们可以试试吗? –

+0

'set -vx'或将shebang更改为'/ bin/bash -x'来打开调试。检查输出,看看是否按预期展开了所有内容(可能是引用)...请参阅[bash调试](http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html) –

+0

说明已更新输入样本和调试信息。 – mirix

回答

1

的问题是你砍在测试表达两个字符,它应该是:

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 

你应该使用切-c22-22而非-c22-23。我在命令替换周围删除了双引号,因此它也会为您删除空格。

+0

你说得对。非常感谢! – mirix

+0

我不认为这是真的。括号将启动一个新的子shell和一个新的“引用范围”。作为一个例子,试着用外部引号和不用外部引号:'echo“$(echo”foo bar“)”'(确保你在foo和bar之间使用多个空格:markdown不会让我在这里执行) –

+0

@glenn你可能是对的。奇怪的是,如果在命令替换周围使用双引号,则解决方案将不起作用。也许这是来自bash的错误。有问题的行是'[“$(echo”$ pdb“| cut -c22-23)”==“$ {chain [$ c]}”]' –