我有一个sas日志文件,我只想列出两个单词之间的那些行:data
和run
。
文件可以在许多行中包含许多这样的单词,例如:
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)
用于换行符)。我可能还想在
data
和run
之间的模式中添加其他单词,例如:MPRINT: data xxx;
fffff
NOTE: ffdd
set fff;
xxxxxx
MPRINT: run;
data fff;
yyyyyy
run;
在某些情况下,我只想列出
data
和run
之间的行,其中某些行中有set
字。我知道有很多类似的线程,但是当关键字可以重复多次时,我没有找到任何线程。
我不熟悉
awk
或sed
,但如果可以帮助的话,我也可以使用它。[编辑]
请注意,
data
和run
不一定在行的开头(我更新了示例)。在data
和data
之间也不能有其他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/