如何使用awk交换最后两列的位置?

3

我正在尝试这个

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

如果我用tab替换input_text.txt文件中的spaces,就会出现相同的情况。
 1 7 9 5 2 11 0

我正在 Windows 10 上使用 Cygwin


1
使用以下命令:awk 'NF>3 {B=$(NF-1);A=$NF; $NF=$(NF-2); $(NF-1) = $(NF-3); $(NF-2)=A; $(NF-3) = B} 1' input_text.txt - anubhava
那只是删除了前三列。:( 运行 awk 'NF>3 {B=$(NF-1);A=$NF; $NF=$(NF-2); $(NF-1) = $(NF-3); $(NF-2)=A; $(NF-3) = B} 1' input_text.txt 的输出结果是:11 0 5 2 - Barzi2001
1
我刚刚编辑了问题,添加了所需的输出 :) - Barzi2001
2
如果您的文本文件使用DOS的\r\n行尾,您需要从$NF中删除\r - glenn jackman
3个回答

2

要将最后的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 命令来交换值:
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 {
$0 = gensub(/(\S+\s+\S+)(\s+)(\S+\s+\S+)$/, "\\3\\2\\1", "1")} 1' file

1 7 9 5 2 11 0

0
请使用您提供的示例尝试以下代码。这是通用代码,其中有两个名为fromFieldstoFieldsawk变量。因此,您需要像这样给出它们的值:假设您想要用第6个字段替换第4个字段的值,并用第7个字段替换第5个字段的值,那么您将设置如下:fromFields="4,5"toFields="6,7"。我假设用户会理解所给定的值与输入文件相对应。
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

@Ubaldo Tiberi,您能否告诉我我的答案是否对您有用? - RavinderSingh13

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接