使用grep,我知道如何将上下文设置为固定的行数。是否可以根据任意字符串条件显示上下文,比如将after-context设置为“直到下一个空行”?或者可能是其他工具的组合?基本上我有一个连续行的日志文件,用空行分隔“事件”我想在日志文件中搜索一个字符串,但显示整个事件...。
6mw9ycah1#
听起来您需要sed:
sed
sed -n '/pattern/,/^$/p' file
默认情况下不打印(-n)。对于匹配/pattern/直到空行/^$/的行,打印。
-n
/pattern/
/^$/
mzsu5hc02#
一个简单的解决办法是:
awk '/pattern/' RS= input-file
将RS设置为空字符串会使awk将空行视为记录分隔符,而简单规则/pattern/会使awk打印与模式匹配的任何记录,模式可以是任何扩展的正则表达式。
mwg9r5ms3#
下面是一个(经过测试的)awk解决方案,为了便于阅读,将其分成多行:
awk
awk '/pattern/ {do_print=1} do_print==1 {print} NF==0 {do_print=0}' input_file
此脚本还将打印空白行,以便更容易地在视觉上分隔不同的匹配块。
说明:
'...'.
/pattern/ {do_print=1}
pattern
do_print
do_print==1 {print}
NF==0 {do_print=0}
NF == 0
5ssjco0h4#
就我个人而言,我喜欢@William Pursell的答案,因为before上下文通常很有用(例如,当用grep来查找ini文件中的内容时)。如果你只需要awk的after上下文,你可以这样做:
ini
$ cat demo.ini [foo] aaa = 1 bbb = 2 ccc = 3 [bar] eee = 8 fff = 0 ggg = 1 [baz] xxx = 1 yyy = 0 zzz = 2 $ awk '/bar/,/^$/' demo.ini [bar] eee = 8 fff = 0 ggg = 1 $ awk '/fff/,/^$/' demo.ini fff = 0 ggg = 1 $
与RS=版本比较:
RS=
$ awk '/bar/' RS= demo.ini [bar] eee = 8 fff = 0 ggg = 1 $ awk '/fff/' RS= demo.ini [bar] eee = 8 fff = 0 ggg = 1
bn31dyow5#
我扩展了上面的解决方案,在各部分之间加入了空行:awk '/模式/' RS=**ORS="\n\n”**输入文件
5条答案
按热度按时间6mw9ycah1#
听起来您需要
sed
:默认情况下不打印(
-n
)。对于匹配/pattern/
直到空行/^$/
的行,打印。mzsu5hc02#
一个简单的解决办法是:
将RS设置为空字符串会使awk将空行视为记录分隔符,而简单规则
/pattern/
会使awk打印与模式匹配的任何记录,模式可以是任何扩展的正则表达式。mwg9r5ms3#
下面是一个(经过测试的)
awk
解决方案,为了便于阅读,将其分成多行:此脚本还将打印空白行,以便更容易地在视觉上分隔不同的匹配块。
说明:
awk
:调用awk
工具-它按顺序一次一行地计算输入。'...'.
:单引号内的所有内容都作为指令提供给awk
。在本例中,我们在每行执行引号内的指令。/pattern/ {do_print=1}
:只要一行包含“pattern
“,就打开do_print
标志do_print==1 {print}
:如果do_print
标志设置为on,则打印当前行。NF==0 {do_print=0}
:NF代表字段数。awk
默认情况下用空格和制表符分隔每一行,以便将一行分成多个字段。在这种情况下,通常一个空白行没有字段-因此,当我们看到一行带有NF == 0
时,我们关闭do_print
标志以停止打印5ssjco0h4#
就我个人而言,我喜欢@William Pursell的答案,因为before上下文通常很有用(例如,当用grep来查找
ini
文件中的内容时)。如果你只需要awk
的after上下文,你可以这样做:与
RS=
版本比较:bn31dyow5#
我扩展了上面的解决方案,在各部分之间加入了空行:
awk '/模式/' RS=**ORS="\n\n”**输入文件