Text-Processing

在 POSIX sed 中,句點(點)是否與多行模式空間中的換行符匹配?

  • December 26, 2015

在 GNU sed 中它可以工作。例如,這匹配多行模式空間中的兩個空行(使用創建N

/^\n$/

這是標準嗎?

是的。

基本/擴展正則表達式

句點在括號表達式.之外使用時是一個[``]

$$ n $$ $$ BE $$RE 應匹配支持的字元集中除 NUL 之外的任何字元。

許多 POSIX 正則表達式實現*(例如grepor sed)*在匹配換行符時沒有困難,因為.不會匹配它,而是因為它們的輸入分隔符是換行符 - 因此它們在掃描的字元串中根本沒有任何換行符匹配。

POSIXgrep永遠無法匹配換行符 - 它與空字元串同義grepsed是相似的,除了 ased可以根據腳本命令執行編輯或拉入額外的輸入,並且這些結果可能包括模式空間中的換行符,即使它們永遠不會在那裡發生。但是,在這種情況下,.將匹配\newline。

我知道的幾乎任何 POSIX 實現都無法完成的一件事是匹配^換行符的補碼。這是因為反斜杠在括號表達式\中代表自身,因此那裡的轉義僅表示and 。因為在正則表達式中包含文字換行符通常也是一種語法錯誤*(儘管**我知道這是一個例外),所以您不能便攜。[``]``\n``\``npax[^<newline>*]

一個理智的實現應該處理"[$(printf '\1-\11\13-\377')]",但這會限制多字節場景中的匹配。

還有:"\(\([^[:space:]]*[[:blank:]$(printf '\r\v\f')]*\)*\)"但這有點笨拙。

但是,您可以便攜地做的是暫時將模式空間中的所有換行符與其他字元交換*(當然反之亦然)*,然後匹配該其他字元的補碼。

例如:

printf %s\\n "a a" "b b" "c c" |
sed -e 'H;1h;$!d;x;l' -e '# slurps input to last line - usually a bad idea'   \
   -e 'y/ \n/\n /;l' -e '# transliterates spaces and newlines at once'       \
   -e 's/[^ ]*//2;l' -e '# substitutes away 2cd sequence of not spaces'      \
   -e 'y/ \n/\n /;l' -e '# transliterates spaces and newlines again'

a a\nb b\nc c$
a\na b\nb c\nc$
a\na  c\nc$
a a\n\nc c$
a a

c c

那個小腳本中有 4 個look 命令 - 每次在找到最後一行後更改模式空間時使用一個。每個look 命令對應於上面的前四個輸出行之一,很容易用尾隨$字元標記。

最後三行是sed預設情況下列印到標準輸出的所有編輯的結果。第二行完全是空的,因為sed替換掉了空格字元補碼的第二個序列,它匹配了模式空間中除了輸入換行符之外的所有字元,所以第二個序列是整個第二行,減去它的尾隨換行符分隔符。

重要的是,這是因為點*(或其更具限制性的[括號表達式]替代)*匹配換行符。

引用自:https://unix.stackexchange.com/questions/251550