使用grep / sed / awk在2个关键字之间列出行

时间:2019-07-16 10:18:36

标签: regex linux grep

我有一个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

3 个答案:

答案 0 :(得分:2)

您可以在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

答案 1 :(得分:1)

对于我所理解的,以下将解决问题

import netCDF4 as nc    
import pandas as pd
N = 100 # With N = 100, python crashes
# It does not crash if I set N = 50

dataset = nc.Dataset('test.nc', 'w')
for i in range(0,N):
   A = pd.DataFrame(data = [1,2,3,4])
   grpid = dataset.createGroup(str(i))

   grpid.createDimension('Rows', A.shape[0])
   grpid.createDimension('Columns', A.shape[1])

   B = grpid.createVariable('B', 'd', ('Rows', 'Columns'))

   B[:,:] = A.values.astype('d')

dataset.close()

请注意,可以通过[a-z | A-Z] {5}之类的内容来改进数据后的“。*”。您可以防止匹配单词数据的中间部分

从那里匹配从数据 set 的位置已经需要一些外部决策过程,因此命令将是

sed -n '/data.*;/,/run;/p' $FILENAME

(可能是从https://strapi.io/documentation/3.0.0-beta.x/guides/models.html#lifecycle-callbacks中学到的)

答案 2 :(得分:0)

只需尝试(?s)data.+?run;

说明:

(?s)-单行模式,.匹配换行符

data-从字面上匹配data

.+?-匹配任何一个或多个字符(包括neline),由于?而非贪婪

run;-从字面上匹配run;

Demo