我想知道的是如何打印一系列模式,但仅限于它包含特定模式。
例如:
我有一个包含以下内容的文件:
HEADER 1
AAA
BBBBBBB
MSG:testing
CCCCCC
DDD
PAGE 1
HEADER 2
EEE
FFFFFF
GGG
HHH
PAGE 2
我想从任何HEADER
打印到任何PAGE
,但前提是它包含模式MSG
我想要的结果是只打印这些部分:
HEADER 1
AAA
BBBBBBB
MSG:testing
CCCCCC
DDD
PAGE 1
到目前为止我所拥有的是:sed -n -e '/HEADER /,/PAGE /p' inputfile.txt > outputfile.txt
我愿意接受任何建议,包括使用Awk或Grep。
提前致谢。
答案 0 :(得分:1)
此
sed '/HEADER/ { :a N; /PAGE/!ba; /MSG/!d }' inputfile.txt
的工作原理如下:
/HEADER/ { # in a line that contains HEADER
:a # jump label for looping
N # fetch next line, append to pattern space
/PAGE/!ba # if the pattern space doesn't contain PAGE (this
# is the case if the new line doesn't), go back to :a
/MSG/!d # if the block that's now in the pattern space doesn't
# contain MSG, discard it
}
这会从文件中删除有问题的范围,并保留其他所有内容。要仅打印匹配范围并丢弃范围之间的垃圾数据,
sed -n '/^HEADER/ { :a N; /PAGE/!ba; /MSG/p }' inputfile.txt
这将删除-n
的默认打印操作,并使用/MSG/p
显式打印匹配的范围,而不是删除不匹配的范围。
答案 1 :(得分:0)
如果您的日期以空格分隔,则可以使用此gnu awk
awk -v RS= '/MSG/' file
HEADER 1
AAA
BBBBBBB
MSG:testing
CCCCCC
DDD
PAGE 1
通过将RS
设置为空,awk
在块模式下工作,然后只需选择正确的块。
这使用HEADER
作为分隔符。
awk -v RS="HEADER" '/MSG/ {print RS$0}' file
HEADER 1
AAA
BBBBBBB
MSG:testing
CCCCCC
DDD
PAGE 1
答案 2 :(得分:0)
sed -n '/^HEADER/,/^PAGE /!d;H;/^HEADER/h;/^PAGE / {x; /\nMSG/ p;}' YourFile
假设只有且始终以HEADER开头并以PAGE(在不同的行上)结束
阐释:
HEADER
和PAGE
之间,请将其删除HEADER
,则将其写入保留缓冲区(覆盖)PAGE
答案 3 :(得分:0)
这可能适合你(GNU sed):
sed '/HEADER/!{H;$!d};x;/MSG/!d' file
如果该行不包含HEADER
,则将其附加到保留空间,如果不是最后一行,则将其删除。这意味着任何其他行(包含HEADER
或最后一行的行)将与保留空间交换,如果模式空间(多行以前保留空间)不包含MSG
,则将其删除。将打印包含MSG
的行。