簡體   English   中英

如何在 GNU awk 中設置多字符記錄分隔符 RS 使其包含新行?

[英]How to set a multicharacter record separator RS in GNU awk so it encompasses the new lines?

我正在使用 GNU Awk 4.1.3。 我想處理這個文件:

$$$$
1
1
$$$$
2
2
$$$$
3
3
$$$$
1
clave
2
$$$$
5
5
$$$$

當給定的塊中包含文本“clave”時,打印“$$$$”和下一個“$$$$”之間的行塊。 也就是說,對於給定的示例,我想要這個輸出:

1
clave
2

我的解決方案是將記錄分隔符RS設置為字符串“$$$$”。 由於它是一個特殊字符,我需要對其進行轉義,因此它最終類似於RS='\\\\$\\\\$\\\\$\\\\$'

awk -v RS='\\$\\$\\$\\$' '/clave/' file

這樣做的問題是結果在塊之前和之后包含一個新行:

$ awk -v RS='\\$\\$\\$\\$' '/clave/' file

1
clave
2

這是因為“$$$$”的結尾和“1”之間有一個新行,“2”和下一個“$$$$”之間也有一個新行。

為了避免這種情況,我在記錄分隔符的兩端添加了新行,因此它變為RS=' \\n \\$\\$\\$\\$ \\n ' 它運作良好:

$ awk -v RS='\n\\$\\$\\$\\$\n' '/clave/' file
#            ^^^           ^^
1
clave
2

但是,這變得非常復雜,我想知道在記錄分隔符中包含新行是否會產生一些我不知道的副作用。

為此,我想知道:如何設置記錄分隔符以使其包含新行? 我的方法是否有效,還是應該因為我的方法有一些缺點而選擇其他選擇?

您應該在 4 $ s 之前和之后的換行符上進行匹配,因為那是真正的分隔符(它自己的一行上的 4 $ s 字符串),如果 4 $ s 出現在您的數據中,其他任何事情都可能失敗。 $ s的第一刺當然不會有換行符,它會匹配字符串開始指示符( ^ ),因此您需要使用:

$ awk -v RS='(^|\n)[$]{4}\n' '/clave/' file
1
clave
2

我發現[$]\\\\$更容易閱讀,YMMV。

您在前后各有一個換行符,因為在您的文件中$$$$前后各有一個新行,並且通過將RS設置為$$$$您將這些換行符保留在記錄中。

更改您的RS以包含換行符或在之前和換行符之前開始或在換行符之后結束,以便記錄沒有這些換行符:

awk -v RS='(^|\n)\\${4}(\n|$)' '/clave/' fike

1
clave
2

另請注意,您可以使用固定長度量詞\\\\${4}而不是\\\\$\\\\$\\\\$\\\\$

暫無
暫無

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

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