簡體   English   中英

RS以AWK語言

[英]RS in awk language

我正在學習awk編程語言,並且在這里遇到了問題。

我有一個文件(awk.dat),具有以下內容:

Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci, euismod id nisi eget, interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat, et facilisis.

我正在使用以下命令:

awk 'BEGIN{RS="*, *";ORS="<<<---\n"} {print $0}' awk.dat

返回錯誤:

awk: run time error: regular expression compile failed (missing operand)
*, *
    FILENAME="" FNR=0 NR=0

同時,如果我使用以下命令: awk 'BEGIN{RS=" *, *";ORS="<<<---\\n"} {print $0}' awk.dat ,它給了我所需的結果。

我需要了解這一部分: RS=" *, *" ,雙引號之間的空間的意義*之前,由於它的投擲的錯誤。

預期產量:

Lorem ipsum dolor sit amet<<<---
consectetur adipiscing elit.
Maecenas pellentesque erat vel tortor consectetur condimentum.
Nunc enim orci<<<---
euismod id nisi eget<<<---
interdum cursus ex.
Curabitur a dapibus tellus.
Lorem ipsum dolor sit amet<<<---
consectetur adipiscing elit.
Aliquam interdum mauris volutpat nisl placerat<<<---
et facilisis.
<<<---

謝謝。

"[space1]*,[space2]*"

是一個正則表達式,它與以下字符串匹配:

零個或多個空格(space1),后跟一個逗號,然后是零個或多個空格(space2)

第一個"*,[space]*"是錯誤的,因為*在正則表達式中具有特殊含義。 這意味着將匹配的組/字符重復零次或多次。 您不能一開始就將其放置。

請注意,根據POSIX, RS被定義為單個字符而不是正則表達式。

RS字符串值的第一個字符應為輸入記錄分隔符; 默認情況下為<newline>。 如果RS包含多個字符,則結果不確定。 如果RS為空,則記錄由由<newline>加上一個或多個空行組成的序列分隔,開頭或結尾的空行在輸入的開頭或結尾不應導致空記錄,而<newline>應不管FS的值是多少,始終是字段分隔符。

來源: Awk Posix標准

這意味着RS=" *, *"導致未定義的行為

實現POSIX擴展的其他版本的awk,對於RS含義可能有不同的方法。 例如GNU awk和mawk。 兩者都將RS實現為正則表達式,但是兩種實現都略有不同。 <asterisk>用法的摘要如下:

| RS   | awk (posix)  | gawk             | mawk             |
|------+--------------+------------------+------------------|
| "*"  | "<asterisk>" | "<asterisk>"     | "<asterisk>"     |
| "*c" | undefined    | "<asterisk>c"    | undefined        |
| "c*" | undefined    | "","c","ccc",... | "","c","ccc",... |

c is any character

上面應該解釋OP的錯誤,因為根據mawk RS="*, *"是無效的正則表達式。

$ echo "abc" | ./mawk '/*c/'
mawk: line 1: regular expression compile failed (missing operand)

GNU awk:GNU awk的手冊規定如下:

使用gawkRS的值不限於一個字符的字符串。 它可以是任何正則表達式 (請參閱Regexp )。 (ce)通常,每條記錄在與正則表達式匹配的下一個字符串處結束; 下一條記錄從匹配字符串的末尾開始。

來源: GNU awk手冊

為了了解<asterisk>在GNU awk中的正則表達式中的用法,我們發現:

<星號> *此符號表示前面的正則表達式應重復多次以找到匹配項。 例如, ph**符號應用於前面的h並查找一個p匹配項,后跟任意數量的h s。 如果不存在h則也僅匹配p

要了解*工作原理,有兩點要* 首先, *僅適用於單個前面的正則表達式分量(例如,在ph* ,它僅適用於h )。 要使*應用於較大的子表達式,請使用括號: (ph)*匹配phphphphphph等。

其次, *查找盡可能多的重復。 如果要匹配的文本是phhhhhhhhhhhhhhooey ,則ph*匹配所有h s。

來源: GNU正則表達式運算符

但必須指出的是:

POSIX awk和gawk中, *+? 當正則表達式中沒有任何運算符時,運算符將代表自己。 例如, /+/匹配文字加號。 但是,awk的許多其他版本將這種用法視為語法錯誤。

來源: GNU正則表達式運算符

因此,設置RS="*, *"意味着它將與字符串"*,""*, ""*, " ,...相匹配。

$ echo "a,b, c" | awk 'BEGIN{RS="*, *"}1'
a,b, c
$ echo "a*,b, c" | awk 'BEGIN{RS="*, *"}1'
a
b, c

mawk: GNU awk的手冊規定如下:

12.多行記錄
由於mawkRS解釋為正則表達式 ,因此多行記錄很容易。

資料來源: man mawk

11.分割字符串,記錄和文件
Awk程序使用相同的算法通過split()將字符串拆分為數組,並記錄到FS字段中。 mawk使用基本上相同的算法將文件拆分為RS記錄。

Split(expr,A,sep)工作方式如下:

  1. <snip>
  2. 如果sep = " " (單個空格),則從expr的前后修剪<SPACE>,並且sep變為<SPACE>。 mawk將<SPACE>定義為正則表達式/[ \\t\\n]+/ 否則, sep會被視為正則表達式, 只是對於長度為1的字符串會忽略元字符 ,例如split(x, A, "*")split(x, A, /\\*/)相同。
  3. <snip>

資料來源: man mawk

該手冊提及應如何解釋以元字符開頭的正則表達式(例如“ * c”)


注意:在GNU awk部分中,我介紹了POSIX awk,因為根據POSIX,形式為"*, "的正則表達式會導致未定義的行為。 (這與定義RS無關,因為RS在POSIX awk中始終不是ERE)

awk實用程序應使用擴展的正則表達式符號(請參閱XBD 擴展的正則表達式

來源: Awk Posix標准

*+?{除在方括號表達式中使用時,<asterisk>,<加號>,<question-mark>和<left-brace>應該是特殊的(請參閱RE方括號表達式)。 以下任何一種用途都會產生不確定的結果:

  • 如果這些字符首先出現在ERE中 ,或者緊隨未轉義的<vertical-line>,<circumflex>,<dollar-sign>或<left-parenthesis>之后出現
  • 如果<left-brace>不是有效間隔表達式的一部分(請參閱匹配多個字符的ERE)

來源: POSIX擴展正則表達式

您能否再嘗試一次。

awk '{gsub(", ","<<<---" ORS)} 1;END{print "<<<---"}'   Input_file

暫無
暫無

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

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