有没有一种简洁的方法让awk打印记录中除第一个字段以外的所有内容?

4

我希望能够将最近的命令历史记录复制到文件中,但是历史记录看起来像这样:

568  find . -name "*.txt" -mtime -1 -print -exec awk '$9 != "" && NR <= 10' {} \;
569  find . -name "*.txt" -mtime -1 -print -exec awk '$9 != "" && n < 10 {print; n++}' {} \;
570  history 10

我想去掉左侧的数字。在awk中是否有一种简短的方法,可以输出除第一个字段外的所有内容,而无需显式地使用$2 $3 $4等来实现?
4个回答

4

如果您不介意前面有一点空间

awk '{$1="";print}' file

否则,可以额外进行一次sub / gsub来解决它。另一种方法是使用for循环。
awk '{for(i=2;i<=NF;i++) printf "%s " ,$i}' file

借鉴pax的解决方案,使用正则表达式的awk版本(谁说你需要sed):)
awk '{gsub(/^ *[^ ]* */,"")}1' file

不需要使用sub/gsub删除前导空格;只需使用substr($0, 2)。这假定OFS默认情况下仅为单个字符长。 - dubiousjim

3

如果您不介意使用除awk以外的其他工具:

history 10 | cut -c 8-

当序列号的位数不同时,这个程序还能正常工作吗? - paxdiablo
我相信这些数字是定宽的,但是使用这种技术是很脆弱的,因为它依赖于可能不可靠的东西。 - Dennis Williamson
实际上,我纠正了一下。刚刚测试过,它们确实是固定宽度的。这可能比任何正则表达式解决方案都要快,所以+1(尽管速度在这里并不是真的很重要)。 - paxdiablo

1
如果您不反对使用其他工具,请尝试sed,它能更好地保留原始文件的空格:
pax> cat qq.in
568  find . -name "*.txt" -mtime -1 -print -exec awk '$9 != "" && NR <= 10' {} \;
569  find . -name "*.txt" -mtime -1 -print -exec awk 'blah blah' {} \;
570  history 10

pax> cat qq.in | sed 's/^ *[^ ]* *//'
find . -name "*.txt" -mtime -1 -print -exec awk '$9 != "" && NR <= 10' {} \;
find . -name "*.txt" -mtime -1 -print -exec awk 'blah blah' {} \;
history 10

它基本上会去除任何前导空格,后跟任何非空格字符,再跟空格字符,有效地削减每行的第一个单词。

如果行格式可以与行开头的任意数字和两个空格联系起来,然后是您感兴趣的文本,您可以使用以下正则表达式稍微改进一下(*后面有两个空格):

sed 's/^[0-9]*  //'

0

这是awk中的另一种选择,也保留空格。

history | awk '{sub($1, "", $0); sub(/^[ \t]+/, "", $0); print}'

请注意,sub 默认为 $0,因此您可以省略它。
history | awk '{sub($1, ""); sub(/^[ \t]+/, ""); print}'

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