大多数带有 awk 的解决方案都会留下空格。这里的选项避免了这个问题。
选项 1
一个简单的剪切解决方案(仅适用于单个分隔符):
command | cut -d' ' -f3-
选项 2
强制 awk 重新计算有时会通过删除第一个字段来删除添加的前导空格 (OFS)(适用于某些版本的 awk):
command | awk '{ $1=$2="";$0=$0;} NF=NF'
选项 3
打印使用printf 格式化的每个字段将提供更多控制:
$ in=' 1 2 3 4 5 6 7 8 '
$ echo "$in"|awk -v n=2 '{ for(i=n+1;i<=NF;i++) printf("%s%s",$i,i==NF?RS:OFS);}'
3 4 5 6 7 8
但是,所有先前的答案都将字段之间的所有重复 FS 更改为 OFS。让我们构建几个不这样做的选项。
选项 4(推荐)
带有 sub 的循环用于删除前面的字段和分隔符。
并使用 FS 的值而不是空间(可以更改)。
更便携,并且不会触发将 FS 更改为 OFS:
注意:^[FS]* 接受带有前导空格的输入。
$ in=' 1 2 3 4 5 6 7 8 '
$ echo "$in" | awk '{ n=2; a="^["FS"]*[^"FS"]+["FS"]+";
for(i=1;i<=n;i++) sub( a , "" , $0 ) } 1 '
3 4 5 6 7 8
选项 5
很可能构建一个不添加额外(前导或尾随)空格的解决方案,并使用来自 GNU awk 的函数 gensub 保留现有空格,如下所示:
$ echo ' 1 2 3 4 5 6 7 8 ' |
awk -v n=2 'BEGIN{ a="^["FS"]*"; b="([^"FS"]+["FS"]+)"; c="{"n"}"; }
{ print(gensub(a""b""c,"",1)); }'
3 4 5 6 7 8
它也可以用来交换一组给定计数n的字段:
$ echo ' 1 2 3 4 5 6 7 8 ' |
awk -v n=2 'BEGIN{ a="^["FS"]*"; b="([^"FS"]+["FS"]+)"; c="{"n"}"; }
{
d=gensub(a""b""c,"",1);
e=gensub("^(.*)"d,"\\1",1,$0);
print("|"d"|","!"e"!");
}'
|3 4 5 6 7 8 | ! 1 2 !
当然,在这种情况下,OFS 用于分隔行的两个部分,并且仍然打印字段的尾随空格。
注意:[FS]* 用于在输入行中允许前导空格。