简洁的方式打印所有行,直到匹配给定模式的最后一行 [英] Succinct way to print all lines up until the last line that matches a given pattern

查看:51
本文介绍了简洁的方式打印所有行,直到匹配给定模式的最后一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图找到一个简洁的外壳,可以给我所有文件中的行,直到某种模式.

I'm trying to find a succinct shell one-liner that'll give me all the lines in a file up until some pattern.

用例将所有行都转储到日志文件中,直到发现一些指示服务器已重新启动的标记.

The use case is dumping all the lines in a log file until I spot some marker indicating that the server has been restarted.

这是一种愚蠢的仅用于shell的方式:

Here's a stupid shell-only way that:

tail_file_to_pattern() {
    pattern=$1
    file=$2

    tail -n$((1 + $(wc -l $file | cut -d' ' -f1) - $(grep -E -n "$pattern" $file | tail -n 1 | cut -d ':' -f1))) $file
}

一种更可靠的Perl方式,可以在stdin上获取文件:

A slightly more reliable Perl way that takes the file on stdin:

perl -we '
    push @lines => $_ while <STDIN>;
    my $pattern = $ARGV[0];
    END {
        my $last_match = 0;
        for (my $i = @lines; $i--;) {
            $last_match = $i and last if $lines[$i] =~ /$pattern/;
        }
        print @lines[$last_match..$#lines];
    }
'

当然,打开文件可以更有效地做到这一点,寻找到最后并寻找直到找到一条匹配的线.

And of course you could do that more efficiently be opening the file, seeking to the end and seeking back until you found a matching line.

很容易打印第一次出现的所有内容,例如:

It's easy to print everything as of the first occurrence, e.g.:

sed -n '/PATTERN/,$p'

但是我还没有想出一种方法来打印 last 中的所有内容发生.

But I haven't come up with a way to print everything as of the last occurance.

推荐答案

这是一个仅使用 sed 的解决方案.要打印 $ file 中的每一行开头,最后匹配 $ pattern 的行:

Here's a sed-only solution. To print every line in $file starting with the last line that matches $pattern:

sed -e "H;/${pattern}/h" -e '$g;$!d' $file

请注意,就像您的示例一样,这仅在文件包含模式的情况下才能正常工作.否则,它将输出整个文件.

Note that like your examples, this only works properly if the file contains the pattern. Otherwise, it outputs the entire file.

下面是它的功能细分,括号中是sed命令:

Here's a breakdown of what it does, with sed commands in brackets:

  • [H]将每行追加到sed的保留空间",但不要将其回显到stdout [d].
  • 遇到图案时,[h]放弃保留空间,然后从匹配的行开始.
  • 当我们到达文件末尾时,将保留空间复制到模式空间[g],以便它将回显到stdout.

还请注意,文件很大时,它可能会变慢,因为任何单遍解决方案都需要在内存中保留很多行.

Also note that it's likely to get slow with very large files, since any single-pass solution will need to keep a bunch of lines in memory.

这篇关于简洁的方式打印所有行,直到匹配给定模式的最后一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆