单行:打印除最后3行以外的所有行?

San*_*ing 8 linux bash perl freebsd

我想模拟GNU head -n -3,它打印除了最后3行之外的所有行,因为head在FreeBSD上没有这个功能.所以我在想类似的东西

seq 1 10 | perl -ne ...
Run Code Online (Sandbox Code Playgroud)

这里我使用了10行,但它可以是任何大于3的数字.

它可以用Perl或其他方式在BASH的FreeBSD上完成吗?

一个超级原始的解决方案

seq 1 10 | sed '$d' | sed '$d' | sed '$d'
Run Code Online (Sandbox Code Playgroud)

mob*_*mob 11

seq 1 10 | perl -e '@x=("")x3;while(<>){print shift @x;push @x,$_}'
Run Code Online (Sandbox Code Playgroud)

要么

perl -e '@x=("")x3;while(<>){print shift @x;push @x,$_}' file
Run Code Online (Sandbox Code Playgroud)

要么

command | perl -pe 'BEGIN{@x=("")x3}push @x,$_;$_=shift @x'
perl -pe 'BEGIN{@x=("")x3}push @x,$_;$_=shift @x' file
Run Code Online (Sandbox Code Playgroud)

  • 与工具的解决方案不同,这不会将整个文件保留在内存中,只读取最后3行. (6认同)

Gre*_*con 9

seq 1 10 | perl -ne 'push @l, $_; print shift @l if @l > 3'
Run Code Online (Sandbox Code Playgroud)


Dig*_*uma 7

纯粹的bash和简单的工具(wc和cut):

head -n $(($(wc -l file | cut -c-8)-3)) file
Run Code Online (Sandbox Code Playgroud)

免责声明 - 我现在无法访问FreeBSD,但这确实适用于OSX bash.

  • 这必须读取文件两次,因此它不适用于管道. (3认同)

too*_*lic 6

这适用于管道和输入文件:

seq 1 10 | perl -e'@x=<>;print@x[0..$#x-3]'
Run Code Online (Sandbox Code Playgroud)

  • 对于大型文件来说,这是一个非理想的解决方案,因为在打印任何内容之前,它会将整个内容放入"@ x"中,必须将整个内容保留在内存中.对于缺乏这种缺点的更简洁的解决方案,请参阅@ greg-bacon的回复. (2认同)

dev*_*ull 5

似乎没有人有使用sedtac,所以这里是一个:

$ seq 10 | tac | sed '1,3d' | tac
1
2
3
4
5
6
7
Run Code Online (Sandbox Code Playgroud)