簡體   English   中英

使用grep / sed / awk在2個關鍵字之間列出行

[英]List lines beetween 2 keywords using grep/sed/awk

我有一個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;

在某些情況下,我只想列出data之間的行,然后在某些行中set單詞的地方run

我知道有很多類似的線程,但是當關鍵字可以重復多次時,我沒有找到任何線程。 我不熟悉awksed但如果可以幫助的話,我也可以使用它。

[編輯]
注意, datarun不一定在行的開頭(我更新了示例)。 datarun之間也不能有其他data

[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命令witn -P (PCRE)選項:

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

對於我所理解的以下將解決問題

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

請注意,可以通過[az | AZ] {5}之類的內容來改進數據后的“。*”,防止在中間的某處匹配單詞數據

從那里到從數據集合的匹配將已經需要一些外部決策過程,因此該命令將是

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

(大概是從如何使用sed / grep提取兩個單詞之間的文本的過程中學到的。

只需嘗試(?s)data.+?run;

說明:

(?s) -單行模式. 匹配換行符

data -從字面上匹配data

.+? -匹配任何一個或多個字符(包括neline),由於以下原因而不貪心?

run; -比賽run; 按照字面

演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM