[英]List lines beetween 2 keywords using grep/sed/awk
我有一個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
之間的行,然后在某些行中set
單詞的地方run
。
我知道有很多類似的線程,但是當關鍵字可以重復多次時,我沒有找到任何線程。 我不熟悉awk
或sed
但如果可以幫助的話,我也可以使用它。
[編輯]
注意, data
和run
不一定在行的開頭(我更新了示例)。 在data
和run
之間也不能有其他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.