grep 倒数第二行

发布于 2024-12-08 13:47:18 字数 99 浏览 0 评论 0原文

就像标题所说,如何使用 grep (或类似的 bash 工具)过滤(可变长度)文件的最后一行之前的行?

也就是说,显示除倒数第二行之外的所有内容。

谢谢

Like the title says, how can I filter with grep (or similar bash tool) the line-before-the-last-line of a (variable length) file?

That is, show everything EXCEPT the penultimate line.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

过期情话 2024-12-15 13:47:18

您可以使用 headtail 的组合,例如:

$ 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 参数中使用负值。)

You can use a combination of head and tail like this for example:

$ cat input 
one
two
three
HIDDEN
four
$ head -n -2 input ; tail -n 1 input 
one
two
three
four

From the coreutils head documentation:

‘-n k’
‘--lines=k’
Output the first k lines. However, if k starts with a ‘-’, print all but the last k lines of each file. Size multiplier suffixes are the same as with the -c option.

So the head -n -2 part strips all but the last two lines of its input.

This is unfortunately not portable. (POSIX does not allow negative values in the -n parameter.)

墨小沫ゞ 2024-12-15 13:47:18

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

更详细;除非我们在最后一行 ($),否则交换模式空间和保持空间(记住当前行;检索上一行,如果有的话)。然后,除非这是第一行,否则打印模式空间中现在的任何内容(前一行,除非我们在最后一行)。

grep is the wrong tool for this. You can wing it with something like

# 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 has built-in arithmetic operators which are more elegant than expr; but expr is portable to other shells.

You could also do this in pure sed but I don't want to think about it. In Perl or awk, it would be easy to print the previous line and then at EOF print the final line.

Edit: I thought about sed after all.

sed -n '$!x;1!p' file

In more detail; unless we are at the last line ($), exchange the pattern space and the hold space (remember the current line; retrieve the previous line, if any). Then, unless this is the first line, print whatever is now in the pattern space (the previous line, except when we are on the last line).

人│生佛魔见 2024-12-15 13:47:18

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

awk oneliner: (test with 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
盛夏已如深秋| 2024-12-15 13:47:18

使用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

Using 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文