如何用 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
变量,名为 fromFields
和 toFields
。所以你需要给出它们的值,比如:假设你想用第 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
我正在尝试这个
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
变量,名为 fromFields
和 toFields
。所以你需要给出它们的值,比如:假设你想用第 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