Shell
如何在 sed 的 s 命令中使用 shell 變數?
我們知道我們可以使用 $ 符號獲取變數的值:
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
替換字元串中的字元解釋。