在awk中打​​印出所有剩余的variables

我正在写一个快速的awk脚本来转换这种格式的行:

AAAA BBBB CCCC DDDD... 

 CCCC AAAA BBBB DDDD... 

这是我的脚本:

 { printf "%s %s %s %s", $3, $1, $2, $4 }; 

这个工作正常,除了当原始input行有超过4个标记,在这种情况下,第5个和以下的标记不打印。

我检查了一些答案,比如使用awk打印所有列从第n个到最后一个,但是他们依赖于将variables设置为"" ,如果这些variables稍后被重用,这似乎会导致问题。

有没有一种简单的方法来取代$4 ,如“从$ 4到行尾的子串”?

在这个简单的情况下,你所需要的是:

 $ awk '{t=$3; $3=$2; $2=$1; $1=t}1' file CCCC AAAA BBBB DDDD 

但一般用GNU awk for gensub()\s\S

 $ awk '{print $3, $1, $2, gensub(/^\s*(\S+\s+){3}/,"","")}' file CCCC AAAA BBBB DDDD 

gensub()只是跳过前三个字段,并将从这一点离开所有字段和字段之间的空间:

 $ cat file AAAA BBBB CCCC DDDD EEEE FFFF GGGG $ awk '{print $3, $1, $2, gensub(/^\s*(\S+\s+){3}/,"","")}' file CCCC AAAA BBBB DDDD EEEE FFFF GGGG 

与其他awk你可以做match()+substr()

 $ awk '{match($0,/^[[:space:]]*([^[:space:]]+[[:space:]]+){3}/); print $3, $1, $2, substr($0,RLENGTH+1)}' file CCCC AAAA BBBB DDDD EEEE FFFF GGGG 

或者sub()和一个变量:

 $ awk '{x=$0; sub(/^[[:space:]]*([^[:space:]]+[[:space:]]+){3}/,"",x); print $3, $1, $2, x}' file CCCC AAAA BBBB DDDD EEEE FFFF GGGG 

使用for循环:

 { printf("%s %s %s", $3, $1, $2); for (i = 4; i <= NF; i++) printf("%s ", $i); printf("\n"); } 

这并不一定“容易”,但并不那么难:

 { printf "%s %s %s ", $3, $1, $2; for (i=4; i<= NF; ++i) { printf "%s ", $i; } printf "\n"; } 

另一种方法,有点聪明:

 { N3 = $3; N2 = $2; N1 = $1; // capture the fields $1 = N3; $2 = N1; $3 = N2; // reorder the fields print; // print the whole record } 

Perl的:

 perl -lane '($F[0], $F[2]) = ($F[2], $F[0]); print "@F"' file