zejun
zejun

Reputation: 33

How to print next few lines after regex match until another regex match?

For instance, there is a piece of text

[task,line:111] first
                second
[demo,line:222] first
[test,line:333] first
[task,line:444] first
                second
                third
[task,line:555] first

I only want the lines with [task] and next lines until another [*] appears. Like below

[task,line:111] first
                second
[task,line:444] first
                second
                third
[task,line:555] first

How can I use awk or other tool in shell script to acomplish it? I just know I can use

awk '/regex/{print $0>"'$output'"}' $file

to get lines with [task] and redirect them to another file.Please help me with this.

Upvotes: 3

Views: 129

Answers (3)

Daweo
Daweo

Reputation: 36873

I would harness GNU AWK for this task following way, let file.txt content

[task,line:111] first
                second
[demo,line:222] first
[test,line:333] first
[task,line:444] first
                second
                third
[task,line:555] first

then

awk 'BEGIN{RS="[";ORS=""}/task/{print "[" $0}' file.txt

gives output

[task,line:111] first
                second
[task,line:444] first
                second
                third
[task,line:555] first

Explanation: I inform GNU AWK that row separator (RS) is [ and output row separator (ORS) is empty string, i.e. row is thing between [ and [, then for each row which has task inside I print it with [ prepended, as ORS is empty string no superfluous newline is added (required newlines are already in row). If you want to know more about RS or ORS read 8 Powerful Awk Built-in Variables – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR

(tested in gawk 4.2.1)

Upvotes: 1

anubhava
anubhava

Reputation: 786339

You may use this awk:

awk 'NF == 2 {isTask = ($1 ~ /^\[task/)} isTask' file

[task,line:111] first
                second
[task,line:444] first
                second
                third
[task,line:555] first

Upvotes: 1

tshiono
tshiono

Reputation: 22087

Would you please try the following:

awk '
    /^\[/ {                                     # the line starts with "["
        if ($1 ~ /^\[task/) f = 1               # set flag for "[task" line
        else f = 0                              # otherwise reset the flag
    }
    f {print}                                   # if flag is set, print the line
' input_file > output_file

Then the output_file will look like:

[task,line:111] first
                second
[task,line:444] first
                second
                third
[task,line:555] first

Upvotes: 2

Related Questions