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
精彩评论