sed:返回最后一次出现的匹配,直到文件末尾
使用 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您的示例脚本在“统计”之前有一个空格,但您的示例数据似乎没有。它有一个正则表达式,假设统计数据位于行首;如果不正确请调整。
当您看到统计信息时,将保留空间替换为当前行 (
h
)。否则,追加到保留空间 (H
)。如果我们没有到达文件末尾,请在此停止 (b
)。在文件末尾,打印出保留空间(x
检索保留空间的内容;p
打印)。在 sed 脚本中,命令可以选择添加“地址”前缀。最常见的是正则表达式,但它也可以是行号。地址
/^Statistics |/
选择与正则表达式匹配的所有行;/^Statistics |/!
选择与正则表达式不匹配的行;和$!
匹配文件中除最后一行之外的所有行。对所有输入行执行没有显式地址的命令。编辑 更详细地解释该脚本,并添加以下内容。
请注意,如果您需要使用 ssh 将其传递到远程主机,则需要额外的引用级别。如果它变得太复杂,一种可能的解决方法是将此脚本存储在远程主机上,并且仅存储
ssh remotehost path/to/script
。另一种可能的解决方法是更改寻址表达式,使它们不包含任何感叹号(这些在命令行上(例如在 Bash 中)是有问题的)。这也比较简单一些!
第三种可能的解决方法是,如果您的 ssh 管道的标准输入未与其他事物相关,则可以从本地主机通过管道输入脚本。
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.
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 justssh 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).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.
如果您有可用的
tac
:If you have
tac
available:这可能对你有用:
This might work for you:
如果您对 awk 解决方案感到满意,那么这种方法是可行的(除了获得额外的空行之外):
If you're happy with an
awk
solution, this kinda works (apart from getting an extra blank line):这也可能有效,是上面其他人给出的 sed 解决方案的稍微简单的版本:
输出:
This might also work, slightly more simple version of the sed solution given by the others above:
Output:
应该可以工作(GNU sed 4.2.1)。
它将整个文件读取为一个字符串,然后用
Statistics
替换从开始到最后一个Statistics
(包括单词)的所有内容,并打印剩余内容。华泰
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) withStatistics
, and prints what's remaining.HTH