使用文件

时间:2015-11-19 13:21:23

标签: bash

我想做一件简单的事情:

要获得单词TER第二次出现的第二个数字,然后将其降低一个并进一步处理。 The tr -s ' '存在,因为文件不是由制表符分隔,而是由不同数量的空格分隔。

我的剧本:

first_res_atombumb= grep 'TER' tata_sbox_cuda.pdb | head -n 2 | tail -1 |tr -s ' '| cut -f 2 -d ' '

echo $((first_res_atombumb-1))

但这只是回归:

255

-1

当然我想要254。

添加| tr -d '\n'也无济于事,究竟是怎么回事?我已经问过几个似乎没人知道的人。

有问题的行看起来像这个

TER     128      DA3     4 

TER     255      DA3     8 

如果我在命令行中应用grep 'TER' tata_sbox_cuda.pdb | head -n 2 | tail -1 | tr -s ' '| cut -f 2 -d ' ',我会得到我所期望的,255

2 个答案:

答案 0 :(得分:2)

用bash,我会写

n_ter=0
while read -a words; do 
    if [[ ${words[0]} == TER ]] && (( ++n_ter == 2 )); then 
        echo $(( ${words[1]} - 1 ))
    fi
done < file

但我会使用awk

awk '$1 == "TER" && ++n == 2 {print $2 - 1}' file

您的代码存在问题:您忘记使用$() command substitution语法

first_res_atombumb= grep 'TER' tata_sbox_cuda.pdb | head -n 2 | tail -1 |tr -s ' '| cut -f 2 -d ' '
# .................^...............................................................................^
echo $((first_res_atombumb-1))

您在grep命令的环境中将变量设置为空字符串。然后,由于您没有捕获该管道的输出,因此将“255”打印到终端。因为在当前shell中未设置变量,所以得到echo $((-1))

您只需要:

first_res_atombumb=$(grep 'TER' tata_sbox_cuda.pdb | head -n 2 | tail -1 |tr -s ' '| cut -f 2 -d ' ')
# .................^^...............................................................................^

但我仍然使用awk。

答案 1 :(得分:0)

如果我正确理解您的问题,您可以使用AWK解决问题:

awk 'BEGIN{v=0} $1 == "TER" {v++;if (v==2) {print $2-1 ;exit}}' tata_sbox_cuda.pdb

说明:

  1. BEGIN{v=0}声明并清空变量。
  2. $1 == "TER"只有在第二次出现TER时才会在{}执行命令。
  3. {v++;if (v==2) {print $2-1 ;exit}}'增加v的值并检查它是否为2,在这种情况下从第二个字段中减去1并显示,然后退出(将使处理更快并且将跳过不必要的行)。