I try to filter the system log by running the sed command like:
error
info_a1
info_a2
info_a3
crit
info_b
error
开发者_开发技巧 info_c1
info_c2
warn
info_d
error
info_x
error
info_p
info
info_w
error
info_z1
info_z2
I expect to get all the error messages like:
error
info_a1
info_a2
info_a3
error
info_c1
info_c2
error
info_x
error
info_p
error
info_z1
info_z2
i use
sed -n "/error/, /[info|warn|crit|]/p"
but it does not work pretty well.
awk '
/^error/ {p=1}
/^(info|warn|crit)/ {p=0}
p
'
If your objective is to print the error message AND the next line after it, then use
cat file_name | grep 'error' -A 1 | grep -v '\-\-'
if you just want to get all lines with "error" in it,
grep "error" file
if you insist on sed
sed -n '/error/p' file
or even awk
awk '/error/' file
or Ruby
ruby -ne 'print if /error' file
Here is a sed
version:
sed -n ':a;/^error/{h;:b;n;${/^[[:blank:]]/{H;x;/^error/{p;q}}};/^[^[:blank:]]/{x;p;x;ba};H;bb}' inputfile
Explanation:
:a # label a
/^error/{ # if pattern space (patt) begins with "error"
h # copy the line to hold space (hold)
:b # label b
n # read the next line
${ # if it's the last line of input
/^[[:blank:]]/{ # if it begins with a space, tab, etc.
H # append it to hold
x # exchange patt and hold
/^error/{ # if patt begins with "error"
p # print it
q # quit
}
}
}
/^[^[:blank:]]/{ # if patt starts with a non-blank (a new block of input has started
x # exchange patt and hold
p # print patt
x # exchange patt and hold
ba # branch to label a
}
H # append patt to hold (save a line of the current block)
bb # branch to b
}
精彩评论