这里是一个链接,用于打印最后一次出现的匹配项之后的所有行。
但是,我只想在最后一次出现匹配后打印两行。我该怎么做呢?
答案1
你可以使用ed
:
printf '%s\n' '?pattern?+1, ?pattern?+2 p' | ed -s file
ed
这会向stdin发送一个命令;读取文件时,该-s
标志禁止输出字节计数。该命令分解如下:
... , ... p
-- 打印给定 (..., ...) 地址范围内的行?pattern?+1
-- 向后搜索然后pattern
添加一个?pattern?+2
-- 向后搜索然后pattern
添加两个
当前默认为文件的最后一行,因此这些搜索会查找pattern
文件中最后一次出现的 。然后,偏移量会选择后面的两条线。
答案2
使用 GNUgrep
和tail
和αГsнιη 的示例文件:
$ cat file
====
1
2
3
4
====
11
22
33
====
111
222
333
444
====
1111
2222
3333
$ grep -A2 "====" file | tail -n2
1111
2222
告诉打印匹配行(在本例中,我们-A2
正在grep
搜索====
)及其后面的两行。然后,tail -n2
仅打印最后两行。
如果您的文件非常大,您可以通过从文件末尾读取tac
并反转逻辑来加快速度:
$ tac file | grep -m1 -B2 "====" | tac |tail -n2
1111
2222
答案3
使用sed
并假设您想要两条线后最后一个匹配pattern
(并且另外假设每条匹配行pattern
与任何其他匹配行至少相隔两行):
$ cat file
a
b pattern
c the 1st
d the 2nd
e the 3rd
1
2
3 pattern
4 the first
5 the second
6 the third
7
$ sed -n -e '/pattern/ { n; N; h; }' -e '$ { g; /./p; }' file
4 the first
5 the second
只要匹配,该sed
命令就会读取 with 中的下一行。之后的行被附加到缓冲区,并且两行都被复制到保留空间(覆盖过去存储在那里的任何内容)。n
pattern
N
h
当我们到达最后一行时,我们得到保留空间,其中现在包含行匹配之后的最新两行,或者如果没有匹配pattern
则为空。pattern
如果缓冲区不为空,则输出。
为了得到三匹配行之后的行pattern
,使用n; N; N; h;
代替n; N; h;
。
获取行匹配后的三行pattern
(现在假设匹配行至少相距三行):
$ sed -n -e '/pattern/ { n; N; N; h; }' -e '$ { g; /./p; }' file
4 the first
5 the second
6 the third
pattern
消除了行匹配相距较远的需要,我们需要检查pattern
我们读取的“后面的行”是否匹配,如果匹配,则从那里重新开始。
sed -n -e ':a' -e '/pattern/ { n; /pattern/ba; N; /pattern/ba; h; }' -e '$ { x; /./p; }' file
答案4
GNU sed在扩展正则表达式模式下-E
将 shell 变量更改为您想要查看的行数。
n=2
sed -Ee '
/\n/q
/pattern/{
:loop
$d;N
/(.*\n){'"$n"'}/!bloop
x
}
$!d;x
/\n.*\n/D
s/.*\n//p;d
' file
- 找到图案线后,设置一个循环以在图案空间中累积线。
- 当看到图案线之后的第n条线时停止(不包括图案线)。
- 将这 n+1 行存储在保留中,如果未达到 eof,则重新开始搜索下一个可能出现的模式。
- 最后在 eof 处,检索保留空间数据并从中剥离第一行(模式行)。