Shell

如何在 sed 的 s 命令中使用 shell 變數?

  • August 7, 2014

我們知道我們可以使用 $ 符號獲取變數的值:

x=3
echo $x
3

是否有其他方法可以在不使用 $ 符號的情況下獲取值。

我問這個是因為 $ 符號是 的特殊字元sed,並且sed: -e expression #1, char 31: unterminated s' command在嘗試執行此操作時出現錯誤:

A=25 #lineNumber
destStr="192.168.1.3 192.168.1.4"
sed ""$A"s/Allow from .*/Allow from $destStr/" -i test2

destStr當我使用轉義字元時,它會列印字元串(而不是值) \

sed ""$A"s/Allow from .*/Allow from \$destStr/" -i test2

使用echo而不是sed

25s/Allow from .*/Allow from  192.168.1.3
192.168.1.4
/ -i test2

正如最終編輯所揭示的那樣,該問題與美元符號無關,而是由 的內容引起的deststr,它不是192.168.1.3 192.168.1.4兩行,而是兩行,一行僅192.168.1.3包含,另一行僅包含192.168.1.4,兩行都以換行符結尾。即變數替換後的實際命令為:

sed "25s/Allow from .*/Allow from  192.168.1.3
192.168.1.4
/" -i test2

現在sed逐行解釋它的命令行,因此它試圖解釋的第一個命令是:

25s/Allow from .*/Allow from  192.168.1.3

這顯然是一個未終止的s命令,因此由此報告sed

現在,您使用 找到的解決方案echo有效,因為

echo $var

使用兩個參數呼叫 echo (因為空格沒有被引用,它被解釋為參數分隔符),第一個是192.168.1.3,第二個是192.168.1.4; 兩者都是 shell 不會進一步解釋的形式。

現在echo只輸出由空格分隔的(非選項)參數,因此您現在得到命令行:

sed "25s/Allow from .*/Allow from  192.168.1.3 192.168.1.4/" -i test2

如預期。

但是請注意,對於命令替換,您應該$()盡可能使用反引號而不是反引號,因為反引號很容易出錯。因此,以下是您想要的:

sed "$A s/Allow from .*/Allow from $(echo $destStr)/" -i test2

請注意,我還利用sed允許地址和命令之間有空格的事實來簡化引用。在這種額外空間不可能的情況下,您還可以使用以下語法:

sed "${A}s/Allow from .*/Allow from $(echo $destStr)/" -i test2

另請注意,這依賴於這樣一個事實,即其中的非空格字元destStr既不會被 shell 解釋,也不會被sed替換字元串中的字元解釋。

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