2012-08-06 52 views
29

是否有(POSIX命令行)的方式来打印所有的文件,除了最后n行?用例,我将有多个未知大小的文件,所有这些文件都包含已知大小的样板页脚,我想删除它们。我想知道是否已经有一个实用程序在自己写之前执行此操作。尾部反转/打印除最后n行之外的所有内容?

回答

33

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

像这样:

head -n -10 textfile 
+8

但在POSIX中,-n必须是正整数。 – choroba 2012-08-06 19:53:37

+1

对于严格的POSIX来说足够了。我应该更清楚我的“最”。如果你打算采用一种更加快速和肮脏的POSIX方法,我会假设'wc -l'加上一些数学会让你有一个值传递给'head' – 2012-08-06 20:06:00

+0

head(1)的大部分实现都缺少这个特性。只有我知道的实现有这个不可移植的代码。 – 2014-05-07 21:23:27

4

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

但是在POSIX中,-n必须是一个正整数。 – choroba 2012-08-06 19:53:21

+4

不幸的是,在BSD派生(即OSX)系统中,负值不是有效的参数-n – Tossrock 2012-08-06 20:07:13

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炮弹,你可能会考虑这一点:

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

所有的这些可能,如果做奇怪的事情一个文件长度不超过10行。

+0

除了用于命令替换的古代反引号外,POSIX还具有更为清晰的'$(...)'语法,它还具有$ ((...))'算术扩展。所以没必要用反引号和'expr'去古代。 [POSIX命令替换](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_03) – geirha 2012-08-06 21:36:58

+1

@geirha:好的一点,这个问题特别提到了POSIX。但是如果有任何POSIX之前的shell仍在使用中,那么了解古代语法可能会有用。 – 2012-08-06 22:02:14

3

没有标准的命令可以做到这一点,但是您可以使用awk或sed填充缓冲区线,并在头部打印完成后从头部打印。例如。使用awk:

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

可能比“WC” +“做数学” +“尾巴”的方法效率较低,而且更容易查看:

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

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

0

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

这个例子给你除了第9

尾-n +10 inputfile中

所有行(是的,也不是第10 ...因为它计算不同...如果你想10,只需键入 tail -n 11 inputfile)

相关问题