我有一个sas日志文件,我只想列出两个单词之间的那些行:datarun

文件可以在许多行中包含许多这样的单词,例如:

MPRINT: data xxxxx;
yyyyy
xxxxxx
MPRINT: run;

fffff
yyyyy

data fff;
fffff
run;

我想要1-4和8-10行。

我尝试了类似的东西egrep -iz file -e '\sdata\s+\S*\s+(.|\s)*\srun\s',但此表达式列出了第一个begin和最后一个end之间的所有行((.|\s)用于换行符)。

我可能还想在datarun之间的模式中添加其他单词,例如:
MPRINT: data xxx;
fffff
NOTE: ffdd
set fff;
xxxxxx
MPRINT: run;

data fff;
yyyyyy
run;

在某些情况下,我只想列出datarun之间的行,其中某些行中有set字。

我知道有很多类似的线程,但是当关键字可以重复多次时,我没有找到任何线程。
我不熟悉awksed,但如果可以帮助的话,我也可以使用它。

[编辑]
请注意,datarun不一定在行的开头(我更新了示例)。在datadata之间也不能有其他run

[Edit2]
正如Tom指出的那样,我要查找的每一行都以MPRINT(...):开头,因此过滤了这些行。
Anubhava答案对最终解决方案的帮助最大,因此将其标记为答案。
最终表达式如下所示:
grep -o path -e 'MPRINT.*' | cut -f '2-' -d ' '|
grep -iozP '(?ms) data [^\(;\s]+.*?(set|infile).*?run[^\n]*\n

最佳答案

您可以在gnu grep(PCRE)选项中使用此-P命令:

grep -ozP '(?ms).*?data .*?run[^\n]*\n' file

如果只想打印从set开始的行,请使用:
grep -ozP '(?ms).*?data .*?^set.*?run[^\n]*\n' file
MPRINT: data xxxxx;
yyyyy
set fff;
xxxxxx
MLOGIC: run;

您可以使用此awk在2个关键字之间进行打印,这些关键字必须包含以set开头的行:
awk '/data / {
   p=1
}
p && !y {
if (/^set/)
   y=1
else
   buf = buf $0 ORS
}
y {
   if (buf != "")
      printf "%s", buf
   buf=""
   print
}
/run/ {
   p=y=0
}' file
MPRINT: data xxxxx;
yyyyy
set fff;
xxxxxx
MLOGIC: run;

如果您只想在awk中的2个关键字之间打印数据,则非常简单:
awk '/data /,/run/' file

关于regex - 使用grep/sed/awk在2个关键字之间列出行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57055044/

10-15 01:37