Sed

sed 不貪心匹配

  • October 12, 2022

我相信 sed 無法進行不貪婪的匹配。有沒有辦法讓 sed 不匹配換行符?

我按如下方式使用 sed,但後者 (.*) 按預期匹配所有內容,但也匹配不需要的新行。

sed -i -s -r 's|^([A-Za-z0-9*()])(.*)|INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "\1\2", "" )|' /path/to/files/*

我得到的輸出是

INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "Some text
", "" )

如果我的輸入文件之一看起來像

Abba
Ebbo
Obbe

…那麼您的命令可以預期將其修改為

INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "Abba", "" )
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "Ebbo", "" )
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "Obbe", "" )

但是,如果您的輸入文件是帶有 CRLF 行結尾的 DOS 文本文件,則結尾的輸入符將導致結果顯示為

", "" )INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "Abba
", "" )INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "Ebbo
", "" )INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "Obbe

…如果文件是在 Unix 系統上處理的。

這是由於終端解釋時輸入符將游標移回行首。

在這種情況下,實際數據是(用\r輸入符號表示)

INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "Abba\r", "" )
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "Ebbo\r", "" )
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "Obbe\r", "" )

要解決此問題,請將輸入文件從 DOS 文本文件轉換為 Unix 文本文件。這可以使用諸如 之類的工具批量完成dos2unix,或者您可以將其作為sed命令的一部分進行:

sed -i \
   -e 's/[[:space:]]$//' \
   -e 's/^[[:alnum:]*()].*/INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "&", "" )/' files

第一個表達式從每行的末尾刪除一個類似空格的字元(輸入符就是其中之一),第二個表達式執行您的替換。

請注意,-s並且-r不需要,因為您不依賴行號,並且您不需要擴展的正則表達式支持。

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