Bra*_*rad 13 sed text-processing
我有一个需要处理的多行日志条目格式。
日志看起来像这样:
--START--
Device=B
Data=asdfasdf
Lorem=Ipsum
--END--
--START--
Device=A
Data=asdfasdf
Lorem=Ipsum
--END--
--START--
Device=B
Data=asdfasdf
--END--
--START--
Device=A
Data=asdfasdf
--END--
--START--
Device=B
Data=asdfasdf
--END--
--START--
Device=C
Data=asdfasdf
Lorem=Ipsum
--END--
Run Code Online (Sandbox Code Playgroud)
我想打印之间的一切--START--与--END--某一特定模式匹配。
例如:
打印所有条目 Device=A
--START--
Device=A
Data=asdfasdf
Lorem=Ipsum
--END--
--START--
Device=A
Data=asdfasdf
--END--
Run Code Online (Sandbox Code Playgroud)
到目前为止我能做的就是写:
sed -e -n '/--START--/,/--END--/p' < input
Run Code Online (Sandbox Code Playgroud)
这有效地打印了输入,但我认为我需要添加{}到过滤器,N然后打印该条件是否匹配。
我也觉得我完全迷失了。
如果单行符合条件,如何打印多行的任何想法?
Joh*_*024 24
$ sed -n '/--START--/{:a;N;/--END--/!ba; /Device=A/p}' file
--START--
Device=A
Data=asdfasdf
Lorem=Ipsum
--END--
--START--
Device=A
Data=asdfasdf
--END--
Run Code Online (Sandbox Code Playgroud)
(以上是在 GNU sed 上测试过的。它必须经过调整才能在 BSD/OSX 上运行。)
这个怎么运作:
/--START--/{...}
每次我们到达包含 的行时--START--,运行大括号内的命令{...}。
:a
定义标签a。
N
阅读下一行并将其添加到模式空间。
/--END--/!ba
除非模式空间现在包含--END--,否则跳回标签a。
/Device=A/p
如果我们到达这里,这意味着模式空间以 开始--START--并以 结束--END--。此外,如果模式空间包含Device=A,则打印 ( p) 它。
sed使用保持空间的其他变体
sed 'H #add line to hold space
/--START--/h #put START into hold space (substitute holded in)
/--END--/!d #clean pattern space (start next line) if not END
x #put hold space into pattern space
/Device=A/!d #clean pattern space if it have not "Device=A"
' file
Run Code Online (Sandbox Code Playgroud)