微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用awk实现尾部

好吧,所以在这里,我正在用这个awk代码挣扎,它应该模拟tail命令

num=$1; { vect[NR]=$0; } END{ for(i=NR-num;i<=NR;i++) print vect[$i] }

所以我想在这里实现的是一个由awk模拟的尾部命令,例如考虑cat somefile | awk -f tail.awk 10应该打印文本文件的最后10行,有什么build议吗?

尾巴最近的文件

如何在远程机器上执行Perl程序?

如何获得“tail -f”的“即时”输出作为input?

在Bash中输出从上到下的文件

将尾部输出redirect到程序中

for(i=NR-num;i<=NR;i++) print vect[$i]

$表示位置参数。 使用只是简单的i :

for(i=NR-num;i<=NR;i++) print vect[i]

为我工作的完整代码是:

#!/usr/bin/awk -f BEGIN{ num=ARGV[1]; # Make that arg empty so awk doesn't interpret it as a file name. ARGV[1] = ""; } { vect[NR]=$0; } END{ for(i=NR-num;i<=NR;i++) print vect[i] }

你可能应该添加一些代码到END来处理NR < num的情况。

所有这些答案存储整个源文件。 这是一个可怕的想法,将打破更大的文件

下面是一个快速方法,只存储要输出的行数(请注意,更高效的tail总是会更快,因为它不会读取整个源文件!):

awk -vt=10 '{o[NR%t]=$0}END{i=(NR<t?0:NR);do print o[++i%t];while(i%t!=NR%t)}'

更清楚地(和更少的代码高尔夫 ):

awk -v tail=10 ' { output[NR % tail] = $0 } END { if(NR < tail) { i = 0 } else { i = NR } do { i = (i + 1) % tail; print output[i] } while (i != NR % tail) }'

可读代码解释:

这使用模运算符来存储所需数量的项目( tail变量)。 由于每一行都被解析,它被存储在较旧的数组值的上面(所以第11行被存储在output[1] )。

END节将增量变量i设置为零(如果我们的行数少于所需的行数)或者行数,这会告诉我们从哪里开始调用已保存的行。 然后我们按顺序打印保存的行。 循环结束时,我们已经返回到第一个值(打印后)。

你可以用i = NR替换if / else节(或者我的高尔夫示例中的三元节),如果你不在意让空行填满要求的数字( echo "foo" |awk -vt=10 …在“foo”之前会有9个空行)。

您需要在awk命令行中添加-v num=10来设置num的值。 在你的最后一个循环中从NR-num+1开始,否则你将以num+1行输出结束。

这可能适合你:

awk '{a=ab $0;b=RS;if(NR<=v)next;a=substr(a,index(a,RS)+1)}END{print a}' v=10

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐