尾部反转/打印除最后n行之外的所有内容?

时间:2012-08-06 19:47:48

标签: linux bash command-line

是否有(POSIX命令行)方式打印所有文件,除了最后n行?用例是,我将有多个未知大小的文件,所有文件都包含一个已知大小的样板页脚,我想删除它。我想知道在自己编写之前是否已有一个实用程序可以执行此操作。

8 个答案:

答案 0 :(得分:39)

head(1)的大多数版本 - 特别是派生的GNU,但不是BSD派生的 - 具有执行此操作的功能。如果您使用负数表示要打印的行数,它将显示除结尾之外的文件顶部。

像这样:

head -n -10 textfile

答案 1 :(得分:12)

可能效率低于“wc”+“做数学”+“尾巴”方法,但更容易看:

tail -r file.txt | tail +NUM | tail -r

其中NUM比您要删除的结束行数多一个,例如+11将打印除最后10行之外的所有行。这适用于BSD,它不支持head -n -NUM语法。

答案 2 :(得分:6)

head实用程序是您的朋友。

来自head的手册页:

-n, --lines=[-]K
     print the first K lines instead of the first 10;
       with the leading `-', print all but the last K lines of each file

答案 3 :(得分:5)

没有标准命令可以执行此操作,但您可以使用awk或sed填充 N 行的缓冲区,并在其填满后从头部打印。例如。用awk:

awk -v n=5 '{if(NR>n) print a[NR%n]; a[NR%n]=$0}' file

答案 4 :(得分:1)

cat <filename> | head -n -10 # Everything except last 10 lines of a file
cat <filename> | tail -n +10 # Everything except 1st 10 lines of a file

答案 5 :(得分:0)

如果页脚以一致的行显示在其他位置,则可以使用sed

sed '/FIRST_LINE_OF_FOOTER/q' filename

打印页脚的第一行;如果你想避免这种情况:

sed -n '/FIRST_LINE_OF_FOOTER/q;p' filename

如果页脚的大小在将来发生变化,这可能比计算行更强大。 (如果第一行改变,它可能不那么健壮。)

如果系统的head命令不支持head -n -10,则另一个选项是预先计算要显示的行数。以下内容取决于特定于bash的语法:

lines=$(wc -l < filename) ; (( lines -= 10 )) ; head -$lines filename

请注意,某些版本的head -NUMBER支持head语法,以实现向后兼容性; POSIX仅允许head -n NUMBER表单。 POSIX也只允许-n的参数为正十进制整数; head -n 0不一定是无操作。

符合POSIX标准的解决方案是:

lines=$(wc -l < filename) ; lines=$(($lines - 10)) ; head -n $lines filename

如果你需要处理古老的POSIX之前的shell,你可能会考虑这个:

lines=`wc -l < filename` ; lines=`expr $lines - 10` ; head -n $lines filename

如果文件长度不超过10行,那么任何这些都可能会产生奇怪的现象。

答案 6 :(得分:0)

很简单。您必须将+添加到您想要避免的行数。

此示例为您提供除前9个

之外的所有行

tail -n +10 inputfile

(是的,不是前10个...因为它有所不同......如果你想要10,只需输入 tail -n 11 inputfile)

答案 7 :(得分:0)

tac file.txt |尾+ [n + 1] | tac

此答案类似于user9645的答案,但是它避免了tail -r命令,这在许多系统中也不是有效的选项。例如,参见https://ubuntuforums.org/showthread.php?t=1346596&s=4246c451162feff4e519ef2f5cb1a45f&p=8444785#post8444785

请注意,在我尝试对其进行测试的系统上,需要+1(括号内),但在您的系统上可能不需要。因此,要删除最后一行,我必须在括号中放入2。这可能与以下事实有关:您需要使最后一行以常规换行符结尾。可以说,这使最后一行成为空白行。如果您不这样做,那么tac命令将合并最后两行,因此删除“最后”行(或第一行到tail命令)实际上将删除最后两行。

对于缺少改进版的head的系统,我的答案应该也是迄今为止列出的最快的解决方案。因此,我认为它是列出的所有答案中最可靠,最快的。