[英]extract content between patterns
在 SUSE Linux 上,我想從文本文件中找到 BEGIN 字符串和 END 字符串之間的完整部分。 我想過使用 sed 或 awk。
或者,我想在另一次運行中搜索下一次出現。
我的挑戰是:
例子
something before ----BEGIN
first paragraph
Text Text Text
Text Text Text
Text Text Text
no ending pattern
something before ----BEGIN
second paragraph
Text Text Text
Text Text Text
Text Text Text
END---- some more text
no beginning pattern
Text Text Text
Text Text Text
END---- some more text
something before ----BEGIN
third paragraph
Text Text Text
Text Text Text
Text Text Text
no ending pattern
something before ----BEGIN
fourth paragraph
Text Text Text
Text Text Text
Text Text Text
END---- some more text
Text Text Text
我期待這樣的事情:
----BEGIN
second paragraph
Text Text Text
Text Text Text
Text Text Text
END----
在另一次運行中,我想找到下一個完整的部分:
----BEGIN
fourth paragraph
Text Text Text
Text Text Text
Text Text Text
END----
在論壇中,我已經可以找到這樣的東西:
tac < file.txt | sed '/END-----/,$!d;/-----BEGIN/q' | tac
但它只查找最后一次出現的字符,並不會剪切開頭和結尾的字符。
不幸的是,我在使用 sed/awk 或 regex 方面沒有經驗。 如果您能給我一些指導,我將不勝感激!
干杯,erd
$ cat tst.awk
BEGIN { beg="----BEGIN"; end="END----" }
sub(".*"beg,beg) { inBlock=1; buf="" }
inBlock {
buf = buf $0 ORS
if ( sub(end".*",end,buf) ) {
print buf ORS
inBlock=0
}
}
$ awk -f tst.awk file
----BEGIN
second paragraph
Text Text Text
Text Text Text
Text Text Text
END----
----BEGIN
fourth paragraph
Text Text Text
Text Text Text
Text Text Text
END----
這是否可行尚不完全清楚,但根據示例輸入做出幾個假設,您可以嘗試:
awk '/BEGIN/ && /END/' RS= ORS='\n\n' input
這將過濾掉您想要的記錄(同樣,我正在根據輸入樣本對您實際想要的內容進行假設),然后您可以輕松地使用第二個 awk 選擇記錄。 例如,要獲取第 n 條記錄,您可以執行以下操作:
N=2; awk '/BEGIN/ && /END/' RS= ORS='\n\n' input | awk 'NR==n' n=$N RS=
把它放在一個循環中,用 N 作為循環計數器,你就有了你(似乎)想要的一切。
BEGIN
和END
之間的緩沖區行在BEGIN
發生時丟棄緩沖區,並在到達END
時打印緩沖區。 請注意,這假設在----BEGIN
之前和END----
之后總是有一個空格。
awk '/BEGIN$/,/^END/ {
if(/BEGIN$/) {
buf=$NF
}
else if(/^END/) {
print buf
print $1
}
else {
buf=(buf ORS $0)
}
}' file
看起來 BEGIN/END 標記不可靠,您依賴於記錄之間的空行, awk
記錄模式支持這種情況。
$ awk -v n=2 -v RS= 'BEGIN {b="BEGIN"; e="END"; h="----"; s=".*"}
NR==n {sub(s h b, h b);
sub(e h s, e h);
print}' file
----BEGIN
second paragraph
Text Text Text
Text Text Text
Text Text Text
END----
這可能對你有用(GNU sed &bash):
b='----BEGIN' e='END----' n=1
sed -En '/'$b'/{:a;N;/'$e'/!ba;x;s/^/x/;/^x{'$n'}$/!{x;b};x;s/.*('$b'.*'$e').*/\1/p}' file
這會收集----BEGIN
和END----
之間的行,然后使用貪婪在結果字符串中找到最后一次出現的----BEGIN
。 作為結果呈現的結果字符串的數量可以由n
變量確定(在上面的示例中,它是第一個)。 第二個示例解決方案如下:
b='----BEGIN' e='END----' n=2
sed -En '/'$b'/{:a;N;/'$e'/!ba;x;s/^/x/;/^x{'$n'}$/!{x;b};x;s/.*('$b'.*'$e').*/\1/p}' file
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.