如何用 awk 交换最后两列对?

How to swap the last two column pairs with awk?

我正在尝试这个

awk '{B=$(NF-1);A=$NF;  $NF=$(NF-2); $(NF-1) = $(NF-3); $(NF-2)=A; $(NF-3) = B; print;}' input_text.txt

但我收到错误消息:

awk: cmd. line:1: (FILENAME=cazzo.txt FNR=2) fatal: attempt to access field -1

示例输入:

$ cat input_text.txt
1 7 9 11 0 5 2

如果我将 input_text.txt 文件中的 spaces 替换为 tabs,也会发生同样的情况。

预期输出:

 1 7 9 5 2 11 0

我 运行 Cygwin Windows 10

您可以试试这个 awk 来交换值:

awk 'NF > 3 {a=$NF; b=$(NF-1); $NF=$(NF-2); $(NF-1)=$(NF-3); $(NF-3)=b; $(NF-2)=a} 1' file

1 7 9 5 2 11 0

如果有 DOS 换行符则使用:

awk -v RS='\r?\n' 'NF > 3 {a=$NF; b=$(NF-1); $NF=$(NF-2); $(NF-1)=$(NF-3); $(NF-3)=b; $(NF-2)=a} 1' file

如果你有 gnu awk 那么你可以使用这种基于正则表达式的方法:

awk -v RS='\r?\n' 'NF > 3 {
[=12=] = gensub(/(\S+\s+\S+)(\s+)(\S+\s+\S+)$/, "\3\2\1", "1")} 1' file

1 7 9 5 2 11 0

要将最后的 n 字段与它们之前的 n 字段交换:

$ awk -v n=2 'NF>=(2*n){ for (i=NF-(n-1); i<=NF; i++) {t=$i; $i=$(i-n); $(i-n)=t} } 1' file
1 7 9 5 2 11 0

$ awk -v n=3 'NF>=(2*n){ for (i=NF-(n-1); i<=NF; i++) {t=$i; $i=$(i-n); $(i-n)=t} } 1' file
1 0 5 2 7 9 11

使用您展示的示例,请尝试以下代码。这是一个通用代码,其中有 2 个 awk 变量,名为 fromFieldstoFields。所以你需要给出它们的值,比如:假设你想用第 6 个字段替换第 4 个字段值,用第 7 个字段替换第 5 个字段值,所以你将它设置为:fromFields="4,5"toFields="6,7"。我假设用户会理解给出的值对于 Input_file.

是可行的
awk -v fromFields="4,5" -v toFields="6,7" '
BEGIN{
  num1=split(fromFields,arr1,",")
  num2=split(toFields,arr2,",")
}
{
  tmp=""
  for(i=1;i<=num1;i++){
    tmp=$arr1[i]
    $arr1[i]=$arr2[i]
    $arr2[i]=tmp
  }
}
1
' Input_file