簡體   English   中英

為什么 sed a 和 sed s 命令在單引號和雙引號下的轉義字符表現不同?

[英]Why do sed a and sed s commands behave differently with respect to escape characters under single quotes and double quotes?

我知道sed表達式中的單引號和雙引號之間存在差異,但我不知道sed ased s表達式之間存在差異。

對於sed s表達式, \t在單引號和雙引號中都被正確地翻譯為制表符。 \\t在雙引號中也做同樣的事情。

# '\t' works for single quotes
$ echo -e "abc\n123" | sed 's|abc|&\n\tdef|'
abc
    def
123

# '\\t' fails for single quotes
$ echo -e "abc\n123" | sed 's|abc|&\\n\\tdef|'
abc\n\tdef
123

# '\t' works for double quotes
$ echo -e "abc\n123" | sed "s|abc|&\n\tdef|"
abc
    def
123

# '\\t' also works for double quotes
$ echo -e "abc\n123" | sed "s|abc|&\\n\\tdef|"
abc
    def
123

但是,在sed a表達式中,我必須在單引號表達式中使用\\t並在帶有雙引號的表達式中使用\\\t

# '\t' fails for single quotes
$ echo -e "abc\n123" | sed '/abc/a\tdef'
abc
tdef
123

# '\\t' works for single quotes
$ echo -e "abc\n123" | sed '/abc/a\\tdef'
abc
    def
123

# '\t' fails for double quotes
$ echo -e "abc\n123" | sed "/abc/a\tdef"
abc
tdef
123

# '\\t' fails for double quotes
$ echo -e "abc\n123" | sed "/abc/a\\tdef"
abc
tdef
123

# '\\\t' works for double quotes
$ echo -e "abc\n123" | sed "/abc/a\\\tdef"
abc
    def
123

由於這種現象,我不得不將我的sed a表達式更改為sed s以統一輸出。 一切都很完美,但我想要一個解釋。

上面的命令在 Ubuntu 20.04 上執行。

sed不知道您使用哪些引號。 shell 解析並刪除引號。 在單引號內,文本完全逐字保留; 在雙引號內,shell 執行變量替換、命令替換和反斜杠處理。 規則很簡單,但有時令人驚訝:簡而言之,反斜杠將下一個字符引用為文字,因此,一對反斜杠被轉換為單個反斜杠。 但是,保留不需要轉義的字符前面的反斜杠。 例如, \t等價於雙引號內的\\t

sed執行另一輪反斜杠處理。 在某些情況下,某些版本的sed\t理解為表示文字制表符,但通常不在aci命令之后的文本中。

這里的實際問題可能實際上是關於a命令的格式。 這在sed版本之間有所不同,但在 Ubuntu 上開箱即用,它只是在命令之后輸出文字文本。 在這種情況下,反斜杠只是一個文字反斜杠,它再次轉義下一個字符以確保它被按字面解釋。 與 shell 不同, sed只是刪除了這個反斜杠。

在 Bash 中,您可以使用$'...' “C-style” 字符串,它可以讓您對文字制表符進行符號編碼。 但是,您需要在幾個地方添加文字反斜杠: sed不接受s命令中未轉義的文字換行符,並且 a 后面a制表符需要反斜杠,以免它作為無關緊要的空格被跳過。

printf '%s\n' abc 123 ghi |
sed -e $'s/abc/&\\\n\tdef/' \
    -e $'/ghi/a\\\tjkl'

重申一下,在將字符串傳遞給命令(在本例中為sed )之前,在$'...'中, \t被 shell 替換為文字制表符, \n替換為換行符等。

在宏偉的計划中,您最好使用比sed更隨意的工具。 awk 更容易閱讀、編寫和調試。

暫無
暫無

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

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