Awk - 打印文件的最后4行

Ted*_*345 3 awk

我有一个测试文件:

1
2
3
4
5
6
7
8
Run Code Online (Sandbox Code Playgroud)

此命令打印文件的最后4行:

$ awk 'BEGIN{"wc -l < file" | getline b}{if(NR>b-4) print}' file
5 
6 
7 
8 
userpc@userpc-desktop
Run Code Online (Sandbox Code Playgroud)

现在我想做同样的事情,但命令系统():

$ awk '{if( NR > (system("wc -l < file")-4) ) print}' file
8 
1 
8 
2 
8 
3 
8 
4 
8 
5 
8 
6 
8 
7 
8 
8 
userpc@userpc-desktop:
Run Code Online (Sandbox Code Playgroud)

如何改进最后一个命令系统()?我还想打印文件的最后4行.谢谢您的帮助.

小智 14

不需要awk,使用tail:

$ tail -4 your_file
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,很好的答案,但问题是关于 awk 和最后一个命令。 (2认同)

Wil*_*ell 9

awk绝对不是正确的工具.这样做很常见:sed '1{N;N;N;}; N; D; $p',你可以用awk做类似的事情:

awk '{for( i=0;i<3;i++) a[i]=a[i+1];a[3]=$0} END {print a[0],a[1],a[2],a[3]}' OFS='\n'
Run Code Online (Sandbox Code Playgroud)

基本上,您可以跟踪看到的最后四行,并在到达文件末尾时将它们全部打印出来.您可以更加模糊和高效:

awk '{a[++i%4]=$0} END {print a[++i%4],a[++i%4],a[++i%4],a[++i%4]}' OFS='\n'
Run Code Online (Sandbox Code Playgroud)

但是,真的,你为什么这样?


Ste*_*eve 6

一种方式使用GNU awk:

awk '{ array[NR]=$0 } END { for (i=NR-3; i<=NR; i++) print array[i] }' file.txt
Run Code Online (Sandbox Code Playgroud)

结果:

5
6
7
8
Run Code Online (Sandbox Code Playgroud)


Wil*_*ell 5

如果您只想要一种机制来改善对wc内部的使用system,请尝试:

awk 'NR > count-4' count=$( wc -l < file ) file
Run Code Online (Sandbox Code Playgroud)

在awk中更多地做到这一点;

awk 'NR==1{ c="wc -l < " FILENAME; c | getline count } NR > count-4' input
Run Code Online (Sandbox Code Playgroud)

这使用NR == 1而不是BEGIN,因为未在BEGIN块内定义FILENAME.请注意,这些都不是system在awk中使用,因为没有好的方法来获取输出system,但你可以做丑陋的事情,如:

awk 'NR==1 { system( "wc -l > tmpfile < " FILENAME ); getline count < "tmpfile" }
    NR > count - 4' input
Run Code Online (Sandbox Code Playgroud)

我无法强调这仅仅是一次学术活动.不要使用awk!