usermrt
usermrt

Reputation: 53

awk: find multiple string and print out

I want to print out the line which contains "number" and lines between "start" and "end" in my input file and print out on the same output file.

I wrote that code

awk -v string="number" '$0~string' Input >> Output
awk ' /start/ {flag=1;next} /end/{flag=0} flag { print $0}' Input >> Output

However, it gave me that output and that is not what I really want

number 1
number 2
start
line 7
line 8
line 9
end
start
line 14
line 15
line 16
end

What I want is though

inputdata:

line 1
line 2
line 3
number 1
line 4
line 5
line6
start
line 7
line 8
line 9
end
line 10
number 2
line 11
line 12
line 13
start
line 14
line 15
line 16
end

output:

number 1
start
line 7
line 8
line 9
end
number 2
start
line 14
line 15
line 16
end

Upvotes: 1

Views: 2088

Answers (4)

oguz ismail
oguz ismail

Reputation: 50815

Using sed

sed -n '/number/p;/start/,/end/p' file

Upvotes: 2

Ed Morton
Ed Morton

Reputation: 204638

Personally, I'd never use a range expression as it makes code for trivial things very slightly briefer but then requires a complete rewrite or duplicate conditions when your requirements change. I'd always just use a flag instead:

$ awk '/start/{f=1} f || /number/{print} /end/{f=0}' file
number 1
start
line 7
line 8
line 9
end
number 2
start
line 14
line 15
line 16
end

The f is for found, not for flag - a flag is the type of the variable, found is what it means. wrt changing number to something else, here's 1 interpretation of what you might mean by that:

$ awk '/start/{f=1} f || sub(/number/,"foobar"){print} /end/{f=0}' file
foobar 1
start
line 7
line 8
line 9
end
foobar 2
start
line 14
line 15
line 16
end

Upvotes: 2

James Brown
James Brown

Reputation: 37464

In awk:

$ awk '/number/;/start/,/end/' file

Output:

number 1
start
line 7
line 8
line 9
end
number 2
start
line 14
line 15
line 16
end

There is a problem in the solution, however. If there is number inside the start-end block, it gets printed out twice. If that is the case with the data, @Ravinder's solution is the fix.

Upvotes: 4

RavinderSingh13
RavinderSingh13

Reputation: 133770

Could you please try following, this will avoid printing string number 2 times in case it is coming in between start and end too.

awk '/start/,/end/{print;next}; /number/'  Input_file

Let's say following is Input_file(I added a small editing in it by adding a string number in it).

cat Input_file
line 1
line 2
line 3
number 1
line 4
line 5
line6
start
line 7
line 8
line 9
end
line 10
number 2
line 11
line 12
line 13
start
line 14
number 13
line 15
line 16
end


awk '/start/,/end/{print;next}; /number/'  Input_file
number 1
start
line 7
line 8
line 9
end
number 2
start
line 14
number 13
line 15
line 16
end

Upvotes: 3

Related Questions