开发者

How to print 5 consecutive lines after a pattern in file using awk [duplicate]

开发者 https://www.devze.com 2023-02-16 20:33 出处:网络
This question already has answers here: Printing with sed or awk a line following a matching pattern (9 answers)
This question already has answers here: Printing with sed or awk a line following a matching pattern (9 answers) 开发者_StackOverflow社区 Closed 3 years ago.

I would like to search for a pattern in a file and prints 5 lines after finding that pattern.

I need to use awk in order to do this.

Example:

File Contents:

.
.
.
.
####PATTERN#######
#Line1
#Line2
#Line3
#Line4
#Line5
.
.
.

How do I parse through a file and print only the above mentioned lines? Do I use the NR of the line which contains "PATTERN" and keep incrementing upto 5 and print each line in the process. Kindly do let me know if there is any other efficient wat to do it in Awk.


Another way to do it in AWK:

awk '/PATTERN/ {for(i=1; i<=5; i++) {getline; print}}' inputfile

in sed:

sed -n '/PATTERN/{n;p;n;p;n;p;n;p;n;p}' inputfile

in GNU sed:

sed -n '/PATTERN/,+7p' inputfile

or

sed -n '1{x;s/.*/####/;x};/PATTERN/{:a;n;p;x;s/.//;ta;q}' inputfile

The # characters represent a counter. Use one fewer than the number of lines you want to output.


awk '
{ 
    if (lines > 0) {
        print;
        --lines;
    }
}

/PATTERN/ {
    lines = 5
}

' < input

This yields:

#Line1
#Line2
#Line3
#Line4
#Line5


grep "PATTERN" search-file -A 5 will do the job for you if decide to give grep a chance.

Edit: You can call grep using system() function from inside your awk script as well.


awk to the rescue!

to print with the pattern line (total 6 lines)

$ awk '/^####PATTERN/{c=6} c&&c--' file

####PATTERN#######
#Line1
#Line2
#Line3
#Line4
#Line5

to skip pattern and print the next five lines

$ awk 'c&&c--; /^####PATTERN/{c=5}' file

#Line1
#Line2
#Line3
#Line4
#Line5


Edit: didn't notice PATTERN shouldn't be part of the output.

cat /etc/passwd | awk '{if(a-->0){print;next}} /qmaild/{a=5}'

or

cat /etc/passwd | awk ' found && NR-6 < a{print} /qmaild/{a=NR;found=1}'

The shortest I can come up with is:

cat /etc/passwd | awk 'a-->0;/qmaild/{a=5}'

Read as a tends to 0. /qmaild/ sets a to 5 :-)


Quick&dirty solution: awk '/PATTERN/ {i=0} { if (i<=5) {print $0}; i+=1} BEGIN {i=6}'


As limited as Johnsyweb's solution but using a different approach and GNU awk's advanced feature allowing full RegEx record separators resulting in a piece of code that, IMHO, is very awk-ish:

awk -F\\\n '{NF=5}NR-1' RS="PATTERN[^\n]*." OFS=\\\n

So if you want a stable solution that is also readable, go along with Dennis Williamson's answer (+1 for that one) but maybe you too simply enjoy the beauty of awk when looking at lines like this.

0

精彩评论

暂无评论...
验证码 换一张
取 消