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.
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
}
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'
But I haven't come up with a way to print everything as of the last occurance.