开发者

sed : printing lines between two words only when one of the line matches a third word or any pattern

开发者 https://www.devze.com 2023-03-11 04:51 出处:网络
i know sed prints lines between words FOO and BAR from test.txt using the following command sed -n \'/FOO/,/BAR/p\' test.txt

i know sed prints lines between words FOO and BAR from test.txt using the following command

  sed -n '/FOO/,/BAR/p' test.txt

but how do i make sed print the lines between FOO and BAR only when one of the lines has a matching pattern

For example, the file text.txt has the following lines :

Error- Undefined port
line1
line2
Undefined port in ALU1 
line3

Error- Undefined port
line4
line5
Undefined port in LSU 
line6

Error- Undefined port
line7
line8
Undefined port in FGU 
line9 

Error- Undefined port
line10
line11
Undefined port in ALU2 
line12

i want to print out lines between the two successive occurrences of the word "Error" only when one of the lines contain the word "ALU".

so i just want to print out the following Error messages :

Error- Undefined port
line1
line2
Undefined port in ALU1 
line3

Error- Undefined port
line10
line11
Undefined port in ALU2 
line1开发者_Python百科2


To achieve this, you need branching in the sed script and hold buffer.

The script uses two buffers: pattern buffer (it is the buffer where sed stores currently processed line and which is used for the pattern matching tests) and the hold buffer (buffer intented for storing previous lines). The thought is to store all lines from the last /Error/ pattern match and check the /ALU/ occurence in the time of next /Error/ match or the end of stream.

sed -n '
# if /Error/ pattern occured, jump to /ALU/ check
/Error/ b alu_check
# else append current line to the hold buffer
H
# if the current line is the last one, jump to /ALU/ check
$ b alu_check
# otherwise jump to end of script (= finish processing of this line)
b
# alu_check:
:alu_check
# exchange current pattern buffer with hols buffer context
x
# print previous record if /ALU/ occured
/ALU/ p
'

x order exchanges the pattern buffer context (current line) with hold buffer context (what is remembered from the last time) - notice that it stores current line with /Error/ pattern to the hold buffer for the next time

H appends current line context to the hold buffer


An awk variant:

 awk 'BEGIN{RS=ORS="\n\n";FS="\n"}/^Error.+ALU/' file

RS (Record Separator) is forced on the blank lines

FS (Field Separator) on single line return

ORS (Output Record Separator) is set on blank line for the output (remove this if you don't need it)

/^Error.+ALU/ If the record (the block of text) starts with Error and contains ALU --> print the block.


awk -v RS= -v ORS="\n\n" '/ALU/' file


Legacy:

awk '{FS="\n";RS=""} $0 ~ /ALU/ {print $0"\n"}' file
0

精彩评论

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