与标题一样,如何使用grep(或类似的bash工具)过滤(可变长度)文件的最后一行?
也就是说,除倒数第二行外,显示所有内容。
由于
答案 0 :(得分:7)
您可以使用head
和tail
的组合,例如:
$ cat input
one
two
three
HIDDEN
four
$ head -n -2 input ; tail -n 1 input
one
two
three
four
来自coreutils head文档:
' - n k'
“--lines = K”
输出前k行。但是,如果k以' - '开头,则打印除每个文件的最后k行之外的所有行。大小乘数后缀与-c选项相同。
因此head -n -2
部分除了输入的最后两行之外的所有部分。
遗憾的是,这不是便携式的。 (POSIX不允许-n
参数中的负值。)
答案 1 :(得分:2)
grep
是错误的工具。你可以使用像
# Get line count
count=$(wc -l <file)
# Subtract one
penultimate=$(expr $count - 1)
# Delete that line, i.e. print all other lines.
# This doesn't modify the file, just prints
# the requested lines to standard output.
sed "${penultimate}d" file
Bash有内置算术运算符,比expr
更优雅;但是expr
可移植到其他shell。
您也可以在纯sed
中执行此操作,但我不想考虑它。在Perl或awk中,很容易打印上一行,然后在EOF打印最后一行。
修改:毕竟我想到了sed
。
sed -n '$!x;1!p' file
更详细;除非我们在最后一行($
),否则交换模式空间和保留空间(记住当前行;检索前一行,如果有的话)。然后,除非这是第一行,否则打印模式空间中的任何内容(前一行,除非我们在最后一行)。
答案 2 :(得分:0)
awk oneliner :(用seq 10测试):
kent$ seq 10|awk '{a[NR]=$0}END{for(i=1;i<=NR;i++)if(i!=NR-1)print a[i]}'
1
2
3
4
5
6
7
8
10
答案 3 :(得分:0)
使用ed
:
printf '%s\n' H '$-1d' wq | ed -s file # in-place file edit
printf '%s\n' H '$-1d' ',p' wq | ed -s file # write to stdout