我想做一件简单的事情:
要获得单词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
答案 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
BEGIN{v=0}
声明并清空变量。$1 == "TER"
只有在第二次出现TER时才会在{}执行命令。{v++;if (v==2) {print $2-1 ;exit}}'
增加v的值并检查它是否为2,在这种情况下从第二个字段中减去1并显示,然后退出(将使处理更快并且将跳过不必要的行)。