【问题标题】:Bash array within a double loop (while/for/if)双循环内的 Bash 数组(while/for/if)
【发布时间】:2011-08-29 08:12:03
【问题描述】:

我正在解析一些文件并将符合两个条件的行复制到一个新文件中。根据数组的大小,脚本的行为会有所不同:

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 也没有输出。如果我删除该条件,它就会起作用。

【问题讨论】:

  • 您能提供一份${pdbid}.pdb 以便我们试用吗?
  • set -vx 或将 shebang 更改为 /bin/bash -x 以打开调试。检查输出以查看所有内容是否按预期扩展(可能是引用)...见bash debugging
  • 使用输入样本和调试信息更新了描述。

标签: arrays bash loops conditional-statements


【解决方案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

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

【讨论】:

  • 我认为这不是真的。括号将开始一个新的子外壳和一个新的“引用范围”。例如,尝试使用或不使用外引号:echo "$(echo "foo bar")"(确保在 foo 和 bar 之间使用多个空格:markdown 不会让我在这里这样做)
  • @glenn 你可能是对的。奇怪的是,如果在命令替换周围使用双引号,解决方案将不起作用。也许这是来自 bash 的错误。有问题的行是[ "$(echo "$pdb" | cut -c22-23)" == "${chain[$c]}" ]
  • 然而,它起作用的原因不是因为你不能混合引号(你可以),而是不引用的副作用是删除任何前导空格,很可能是 $ 的值{chain[0]} 没有前导空格。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
  • 2014-01-21
  • 2019-11-10
  • 2018-11-05
  • 1970-01-01
  • 1970-01-01
  • 2014-08-06
相关资源
最近更新 更多