Using Raku (formerly known as Perl_6)
~$ raku -pe 'if m/^Line \h 5$/ {.put; get.put xx 2; last};' file
OR:
~$ raku -pe 'm/^Line \h 5$/ && .put && get.put xx 2 && last;' file
OR:
~$ raku -ne 'm/^Line \h 5$/ ?? (.put; get.put xx 2; last) !! .put;' file
Here are answers coded in Raku, a member of the Perl-family of programming languages. Raku features high-level support for Unicode, built-in.
In the first pair of answers, the -pe
autoprinting linewise flags are used. Lines will autoprint until the desired line is read, as determined via Regex. At that point the desired line is output
, the code instructs to get
two more lines and out
put them, then that's the last
(i.e. the code exits). Note, for the second of these two examples andthen
can be used instead of &&
.
In the third answer, the -ne
non-autoprinting linewise flags are used. Each line is read into Raku's Test ??
True !!
False ternary operator to find the desired line via Regex. If the desired line is True, it is output
, the code instructs to get
two more lines and out
put them, then that's the last
(i.e. the code exits). If the desired line via Regex is False, it is simply output
and the linewise reading continues, potentially to the end of the file.
Sample Input:
Line 1
FooLine 5
Line 2
Line 55
Line 3
Line 4
Line 5
Line 6
Line 7
Line 5
Line 8
Line 9
Sample Output:
Line 1
FooLine 5
Line 2
Line 55
Line 3
Line 4
Line 5
Line 6
Line 7
NOTE: With all three answers above, blank lines are handled fine, but the code will throw an error if you try to get.put
return lines that don't exist (e.g. if you're too close to the end of the file).
To handle this more gracefully (return whatever lines are available after a matching line, up to the requested number), use the following code which is similar to @terdon's Perl answer. Below set $k
to equal "n+1" lines to return the current line plus "n"-lines that follow ($k=3
gives same output as above):
~$ raku -ne 'my $k=3 if m/^Line \h 5$/; $k.put && --$k; last unless $k;' file
https://docs.raku.org
https://raku.org
tac ip.txt | sed '/Line 5/{n; n; q}' | tac
) but I prefer something else that can be used in a shell script using a variable etc., ideally something like theexec.awk
solution there.tac file | '/Line 5/{n; n; q}' | tac
) was not quite what I wanted, because it didn't stop at the first match, which wouldn't work if there were several instances of the match pattern.