Sed
為什麼我必須在 sed 中對特定字元進行雙重轉義?
這只是一個顯示問題的測試文件。原始部分如下所示:
arch systemd[908]:
現在我可以用“:”字元替換右括號
krys@archeos:~/test]$ cat jctl.log | cut -d " " -f 4,5 | head | sed s/]/:/g arch systemd[908::
當我嘗試更換開口支架時,它不起作用:
krys@archeos:~/test]$ cat jctl.log | cut -d " " -f 4,5 | head | sed s/[/:/g sed: -e expression #1, char 7: unterminated `s' command
然後我用 1 \ 字元轉義了“[”,它仍然不起作用
krys@archeos:~/test]$ cat jctl.log | cut -d " " -f 4,5 | head | sed s/[/:/g sed: -e expression #1, char 7: unterminated `s' command
使用 2 “" 它可以工作:
krys@archeos:~/test]$ cat jctl.log | cut -d " " -f 4,5 | head | sed s/\\[/:/g arch systemd:908]:
所以這是我的問題:
- 為什麼它適用於右括號而不適用於左括號?sed 或 bash 的讀取方式有什麼不同?
- 為什麼必須雙重轉義左括號,而它與右括號完全可以正常工作而根本沒有轉義?
我只是想明白這一點。我現在知道該怎麼做,但我不滿足於不知道細節。
這是因為您沒有引用您的 sed 表達式(壞主意,養成將
sed
命令放在單引號中的習慣)。您需要轉義的原因[
是因為[
它在正則表達式中具有特殊含義,它打開一個字元類(例如[abc]
,將匹配a
、b
或之一c
)。您不需要轉義,]
因為 sed 足夠聰明,可以知道在這種情況下,]
不會關閉字元類,因為沒有[
關閉前。現在,因為您沒有引用 sed 表達式,這意味著 shell在將其傳遞給
sed
. 因此,shell 會看到您的\[
,並使用轉義符將其未轉義地傳遞給 sed。您可以通過以下方式看到這一點set -x
:$ set -x $ sed s/\[/:/g jctl.log + sed 's/[/:/g' jctl.log sed: -e expression #1, char 7: unterminated `s' command
如您所見,實際執行的命令是
sed 's/[/:/g' jctl.log
而不是sed 's/\[/:/g' jctl.log
:shell 已經消耗了轉義。然後這會失敗,因為 sed 正在尋找一個結束]
,沒有找到一個,因此將整個字元串/:/g
視為字元類的內容,因此失敗,因為它找不到s///
命令的結尾。添加第二級轉義允許 shell 消耗一個,然後仍然將
[
轉義傳遞給 sed:$ sed s/\\[/:/g jctl.log + sed 's/\[/:/g' jctl.log arch systemd:908]:
您可以在上面的輸出中看到 sed 現在給出
\[
而不是[
。如果您總是引用您的 sed 命令,所有這些問題都會消失:
$ sed 's/\[/:/g' jctl.log arch systemd:908]: