sed:返回最后一次出现的匹配,直到文件末尾

发布于 2024-12-09 08:37:46 字数 838 浏览 0 评论 0 原文

使用 sed,如何返回直到文件结尾为止最后一次出现的匹配项? (仅供参考,这已被简化)

到目前为止,我已经尝试过:

sed -n '/ Statistics |/,$p' logfile.log

返回从第一个匹配开始的所有行(几乎整个文件)

我也尝试过:

$linenum=`tail -400 logfile.log | grep -n " Statistics |" | tail -1 | cut -d: -f1`
sed "$linenum,\$!d" logfile.log

这可以工作,但不能在一个命令中通过 ssh 连接工作,确实需要将所有内容都集中在一条管道中。

日志文件的格式如下:(

每分钟都有统计头和子数据写入日志文件,该命令的目的是返回最新的统计头以及头后发生的任何相关错误)

Statistics |
   Stuff
   More Stuff
   Even more Stuff
Statistics |
   Stuff
   More Stuff
Error: incorrect value
Statistics |
   Stuff
   More Stuff
   Even more Stuff
Statistics |
   Stuff
Error: error type one
Error: error type two

EOF

回报必须是:

Statistics |
   Stuff
Error: error type one
Error: error type two

Using sed, how do I return the last occurance of a match until the End Of File?
(FYI this has been simplified)

So far I've tried:

sed -n '/ Statistics |/,$p' logfile.log

Which returns all lines from the first match onwards (almost the entire file)

I've also tried:

$linenum=`tail -400 logfile.log | grep -n " Statistics |" | tail -1 | cut -d: -f1`
sed "$linenum,\$!d" logfile.log

This works but won't work over an ssh connection in one command, really need it all to be in one pipeline.

Format of the log file is as follows:

(There are statistics headers with sub data written to the log file every minute, the purpose of this command is to return the most recent Statistics header together with any associated errors that occur after the header)

Statistics |
   Stuff
   More Stuff
   Even more Stuff
Statistics |
   Stuff
   More Stuff
Error: incorrect value
Statistics |
   Stuff
   More Stuff
   Even more Stuff
Statistics |
   Stuff
Error: error type one
Error: error type two

EOF

Return needs to be:

Statistics |
   Stuff
Error: error type one
Error: error type two

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

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

发布评论

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

评论(6

戏剧牡丹亭 2024-12-16 08:37:46

您的示例脚本在“统计”之前有一个空格,但您的示例数据似乎没有。它有一个正则表达式,假设统计数据位于行首;如果不正确请调整。

sed -n '/^Statistics |/h;/^Statistics |/!H;$!b;x;p'

当您看到统计信息时,将保留空间替换为当前行 (h)。否则,追加到保留空间 (H)。如果我们没有到达文件末尾,请在此停止 (b)。在文件末尾,打印出保留空间(x 检索保留空间的内容;p 打印)。

在 sed 脚本中,命令可以选择添加“地址”前缀。最常见的是正则表达式,但它也可以是行号。地址/^Statistics |/选择与正则表达式匹配的所有行; /^Statistics |/! 选择与正则表达式不匹配的行;和 $! 匹配文件中除最后一行之外的所有行。对所有输入行执行没有显式地址的命令。

编辑 更详细地解释该脚本,并添加以下内容。

请注意,如果您需要使用 ssh 将其传递到远程主机,则需要额外的引用级别。如果它变得太复杂,一种可能的解决方法是将此脚本存储在远程主机上,并且仅存储 ssh remotehost path/to/script。另一种可能的解决方法是更改​​寻址表达式,使它们不包含任何感叹号(这些在命令行上(例如在 Bash 中)是有问题的)。

sed -n '/^Statistics |/{h;b};H;${x;p}'

这也比较简单一些!

第三种可能的解决方法是,如果您的 ssh 管道的标准输入未与其他事物相关,则可以从本地主机通过管道输入脚本。

echo '/^Statistics |/h;/^Statistics |/!H;$!b;x;p' |
ssh remotehost sed -n -f - file

Your example script has a space before Statistics but your sample data doesn't seem to. This has a regex which assumes Statistics is at beginning of line; tweak if that's incorrect.

sed -n '/^Statistics |/h;/^Statistics |/!H;$!b;x;p'

When you see Statistics, replace the hold space with the current line (h). Otherwise, append to the hold space (H). If we are not at the end of file, stop here (b). At end of file, print out the hold space (x retrieve contents of hold space; p print).

In a sed script, commands are optionally prefixed by an "address". Most commonly this is a regex, but it can also be a line number. The address /^Statistics |/ selects all lines matching the regular expression; /^Statistics |/! selects lines not matching the regular expression; and $! matches all lines except the last line in the file. Commands with no explicit address are executed for all input lines.

Edit Explain the script in some more detail, and add the following.

Note that if you need to pass this to a remote host using ssh, you will need additional levels of quoting. One possible workaround if it gets too complex is to store this script on the remote host, and just ssh remotehost path/to/script. Another possible workaround is to change the addressing expressions so that they don't contain any exclamation marks (these are problematic on the command line e.g. in Bash).

sed -n '/^Statistics |/{h;b};H;${x;p}'

This is somewhat simpler, too!

A third possible workaround, if your ssh pipeline's stdin is not tied up for other things, is to pipe in the script from your local host.

echo '/^Statistics |/h;/^Statistics |/!H;$!b;x;p' |
ssh remotehost sed -n -f - file
冰魂雪魄 2024-12-16 08:37:46

如果您有可用的 tac

tac INPUTFILE | sed '/^Statistics |/q' | tac

If you have tac available:

tac INPUTFILE | sed '/^Statistics |/q' | tac
南风几经秋 2024-12-16 08:37:46

这可能对你有用:

sed '/Statistics/h;//!H;$!d;x' file
Statistics |
   Stuff
Error: error type one
Error: error type two

This might work for you:

sed '/Statistics/h;//!H;$!d;x' file
Statistics |
   Stuff
Error: error type one
Error: error type two
哭了丶谁疼 2024-12-16 08:37:46

如果您对 awk 解决方案感到满意,那么这种方法是可行的(除了获得额外的空行之外):

awk '/^Statistics/ { buf = "" } { buf = buf "\n" $0 } END { print buf }' input.txt

If you're happy with an awk solution, this kinda works (apart from getting an extra blank line):

awk '/^Statistics/ { buf = "" } { buf = buf "\n" $0 } END { print buf }' input.txt
抚你发端 2024-12-16 08:37:46

这也可能有效,是上面其他人给出的 sed 解决方案的稍微简单的版本:

sed -n 'H; /^Statistics |/h; ${g;p;}' logfile.log

输出:

Statistics |
   Stuff
Error: error type one
Error: error type two

This might also work, slightly more simple version of the sed solution given by the others above:

sed -n 'H; /^Statistics |/h; ${g;p;}' logfile.log

Output:

Statistics |
   Stuff
Error: error type one
Error: error type two
幽蝶幻影 2024-12-16 08:37:46
sed ':a;N;$!ba;s/.*Statistics/Statistics/g' INPUTFILE

应该可以工作(GNU sed 4.2.1)。

它将整个文件读取为一个字符串,然后用 Statistics 替换从开始到最后一个 Statistics(包括单词)的所有内容,并打印剩余内容。

华泰

sed ':a;N;$!ba;s/.*Statistics/Statistics/g' INPUTFILE

should work (GNU sed 4.2.1).

It reads the whole file to one string, then replaces everything from the start to the last Statistics (word included) with Statistics, and prints what's remaining.

HTH

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