4

Given intput:

Via: 1.1.1.1  
not relevant line  
keyword + some text
...
not relevant line N
keyword + some text
...
not relevant line N
Via: 2.2.2.2
not relevant line  
keyword + some text
...
not relevant line N
keyword + some text
...
not relevant line N
Via: 3.3.3.3
not relevant lines
Via: 4.4.4.4
not relevant
Via: 5.5.5.5
not relevant line  
keyword + some text
...
not relevant line N
keyword + some text
...
not relevant line N
not relevant line N
...

Required output:

Via: 1.1.1.1  
keyword + some text A
keyword + some text A
Via: 2.2.2.2
keyword + some text B
keyword + some text C
Via: 5.5.5.5
keyword + some text D
keyword + some text E

keyword string can occur N times in any Via block, or may not occur at all. In the output I need only those Via blocks where keyword occurs together with keyword strings belonging to them. The closest answer I found is here, but I can't make it into what I need.

don_crissti
  • 82,805
Olga
  • 425

3 Answers3

5

With sed:

sed -n '/^Via:/{ x; /keyword/p; d; }; /keyword/H; ${ x; /keyword/p; }' input.txt

Or, if you want keyword anchored at the beginning of line:

sed -n '/^Via:/{ x; /\nkeyword/p; d; }; /^keyword/H; ${ x; /\nkeyword/p; }' input.txt
Satō Katsura
  • 13,368
  • 2
  • 31
  • 50
4

Awk solution:

awk '/^Via:/{ f=1; r=$0; kw=0; next }
     f && /keyword/{ printf "%s%s\n",(!kw)? r ORS:"",$0; kw++ }' file

  • /^Via:/ - capturing line starting with Via: into r variable. Set flag f=1 into "active" state indicating processing of a certain Via block

  • kw - flag denoting the number of "keyword" lines under each Via block

  • f && /keyword/ - while processing lines under Via block - consider only lines matching keyword pattern

0

easy-peasy and simple:

cat input.txt | grep "Via:\|keyword" | grep -B1 "keyword"