shell 如何使得两个文件的中间列相减?

新手上路,请多包涵

两个文件的对应列相减
cat file1
ATOM 1 N ASP 1 104.872 46.138 60.493 1.00 0.00 N
ATOM 2 H1 ASP 1 105.169 46.143 60.702 1.00 0.00 H
ATOM 3 H2 ASP 1 105.241 46.250 60.447 1.00 0.00 H
ATOM 4 H3 ASP 1 105.174 45.965 60.473 1.00 0.00 H
ATOM 5 CA ASP 1 103.501 46.223 60.288 1.00 0.00 C

cat file2
ATOM 1 N ASP 1 104.307 46.895 65.756 1.00 0.00 N
ATOM 2 H1 ASP 1 104.961 47.329 65.120 1.00 0.00 H
ATOM 3 H2 ASP 1 104.636 45.956 65.926 1.00 0.00 H
ATOM 4 H3 ASP 1 104.324 47.367 66.649 1.00 0.00 H
ATOM 5 CA ASP 1 102.945 46.927 65.177 1.00 0.00 C

awk -vOFS='\t' 'NR==FNR{for(i=5;i++<NF;)a[FNR,i]=$i;next}{for(i=;i++<NF;)$i=$i-a[FNR,i]}2' file1 file2
得到的结果是后3列也被减掉
ATOM 1 N ASP 1 0.565 -0.757 -5.263 0 0 0
ATOM 2 H1 ASP 1 0.208 -1.186 -4.418 0 0 0
ATOM 3 H2 ASP 1 0.605 0.294 -5.479 0 0 0
ATOM 4 H3 ASP 1 0.85 -1.402 -6.176 0 0 0
ATOM 5 CA ASP 1 0.556 -0.704 -4.889 0 0 0
我希望的结果是
ATOM 1 N ASP 1 0.565 -0.757 -5.263 1.00 0.00 N
ATOM 2 H1 ASP 1 0.208 -1.186 -4.418 1.00 0.00 N
ATOM 3 H2 ASP 1 0.605 0.294 -5.479 1.00 0.00 N
ATOM 4 H3 ASP 1 0.85 -1.402 -6.176 1.00 0.00 N
ATOM 5 CA ASP 1 0.556 -0.704 -4.889 1.00 0.00 N

阅读 1k
avatarAI BotBETA

你的AWK命令在处理文件时确实存在一些问题。你的目标是对两个文件的中间三列(第5、6、7列)进行相减操作,但是你的AWK命令似乎对所有的列都进行了操作。此外,你在AWK命令中使用了i++<NF,这会导致你的循环从第1列开始,而不是从第5列开始。

为了只处理中间三列,并且保持其他列不变,你可以使用以下的AWK命令:

awk 'NR==FNR { for(i=1;i<=3;i++) a[FNR,i]=$i; next } { for(i=1;i<=3;i++) $i=$i-a[FNR,i]; print }' file1 file2

这个命令的工作原理如下:

  • 当处理第一个文件(file1)时,它会将每行的前三列存储在数组a中。
  • 当处理第二个文件(file2)时,它会从对应的行中取出数组a中存储的值,并从当前行的前三列中减去这些值。
  • 然后,它会打印出修改后的行。

注意,我移除了OFS='\t',因为默认的输出字段分隔符就是制表符。如果你确实需要改变它,你可以再次添加这个选项。

此外,由于你只修改了前三列,所以其他列(包括第4列到最后一列)将保持不变。因此,你应该能得到你期望的结果。

1 个回答
awk 'NR==FNR{for(i=5;i<=NF-3;i++) a[FNR,i]=$i; next}{for(i=5;i<=NF-3;i++) $i=a[FNR,i]-$i}1' file1 file2

ATOM 1 N ASP 0 0.565 -0.757 -5.263 1.00 0.00 N
ATOM 2 H1 ASP 0 0.208 -1.186 -4.418 1.00 0.00 H
ATOM 3 H2 ASP 0 0.605 0.294 -5.479 1.00 0.00 H
ATOM 4 H3 ASP 0 0.85 -1.402 -6.176 1.00 0.00 H
ATOM 5 CA ASP 0 0.556 -0.704 -4.889 1.00 0.00 C

宣传栏