选项 1 到 3 存在多个空格的问题(但很简单)。
这就是开发选项 4 和 5 的原因,它们可以毫无问题地处理多个空格。
当然,如果选项 4 或 5 与 n=0 一起使用,两者都将保留任何前导空格,因为 n=0 表示不拆分。
选项 1
一个简单的剪切解决方案(使用单个分隔符):
$ echo '1 2 3 4 5 6 7 8' | cut -d' ' -f4-
4 5 6 7 8
选项 2
强制 awk 重新计算有时会解决添加前导空格的问题(适用于某些版本的 awk):
$ echo '1 2 3 4 5 6 7 8' | awk '{ $1=$2=$3="";$0=$0;} NF=NF'
4 5 6 7 8
选项 3
打印使用printf 格式化的每个字段将提供更多控制:
$ echo ' 1 2 3 4 5 6 7 8 ' |
awk -v n=3 '{ for (i=n+1; i<=NF; i++){printf("%s%s",$i,i==NF?RS:OFS);} }'
4 5 6 7 8
但是,所有先前的答案都将字段之间的所有 FS 更改为 OFS。让我们为此构建几个解决方案。
选项 4
使用 sub 删除字段和分隔符的循环更便携,并且不会触发将 FS 更改为 OFS:
$ echo ' 1 2 3 4 5 6 7 8 ' |
awk -v n=3 '{ for(i=1;i<=n;i++) { sub("^["FS"]*[^"FS"]+["FS"]+","",$0);} } 1 '
4 5 6 7 8
注意: "^["FS"]*" 用于接受带有前导空格的输入。
选项 5
很可能构建一个不添加额外前导或尾随空格的解决方案,并使用来自 GNU awk 的函数 gensub 保留现有空格,如下所示:
$ echo ' 1 2 3 4 5 6 7 8 ' |
awk -v n=3 '{ print gensub("["FS"]*([^"FS"]+["FS"]+){"n"}","",1); }'
4 5 6 7 8
它也可以用于交换给定计数n的字段列表:
$ echo ' 1 2 3 4 5 6 7 8 ' |
awk -v n=3 '{ a=gensub("["FS"]*([^"FS"]+["FS"]+){"n"}","",1);
b=gensub("^(.*)("a")","\\1",1);
print "|"a"|","!"b"!";
}'
|4 5 6 7 8 | ! 1 2 3 !
当然,在这种情况下,OFS 用于分隔行的两个部分,并且仍然打印字段的尾随空格。
注意1: ["FS"]* 用于在输入行中允许前导空格。