Shell-Script

sed 重複流中的最後一行

  • December 15, 2014

我在類似於此的腳本中有程式碼…

smbconffile="/etc/samba/smb.conf"
sed -i 's/.*[\[CMI\]]/\[CMI\$\]/' $smbconffile && echo "Success" || "Failed"
sed -i 's/.*[\[LOCAL\]]/\[LOCAL\$\]/' $smbconffile && echo "Success" || "Failed"
sed -i 's/.*[\[NATIONAL\]]/\[NATIONAL\$\]/' $smbconffile && echo "Success" || "Failed"

這會將 samba conf (smb.conf) 中的共享名稱更改為 CMI $ , LOCAL $ , 國民$。

我遇到的問題是,在第二個 sed 命令之後,sed 找到“NATIONAL”,但將其重命名為“LOCAL” $ " instead of “NATIONAL $ “。有人看到命令有問題嗎?任何幫助將不勝感激。

您正在將字元類(方括號內的字元列表)與被方括號文字包圍的 smb.conf 共享名稱混合。此外,echo命令格式不正確:在以sed非零狀態退出的情況下,shell 將嘗試呼叫命令Failed

幾點建議:

  1. 刪除字元類(外括號)
  2. 刪除前導.*,這將刪除前導評論等。
  3. sed使用多個語句執行單個命令
  4. 修復錯誤案例消息
sed -i 's/\[CMI\]/\[CMI\$\]/;
       s/\[LOCAL\]/\[LOCAL\$\]/;
       s/\[NATIONAL\]/\[NATIONAL\$\]/' $smbconffile && echo "Success" || echo "Failed"`

您可以使用反向引用來避免在替換錶達式中重新鍵入原始前綴(例如,“[CMI”),但這會使表達式更難閱讀。

另一個建議是使用具有可讀分組和反向引用 IMO 的 Perl:

perl -pi -e 's/(\[(?:CMI|LOCAL|NATIONAL))\]/$1\$]/g' $smbconffile \
   && echo "Success" || echo "Failed"

**編輯:**為了澄清,帶有外括號的原始表達式的問題是您正在創建一個字元類,該字元類與包含(在第一種情況下)[, C, M,的任何字元串匹配I]其後跟 a 的任何順序]。例如:

$ echo '[IMC]' | sed 's/[\[CMI\]]/[something_else]/'
[IM[something_else]

$ echo '[FOOM]' | sed 's/[\[CMI\]]/[something_else]/'
[FOO[something_else]

刪除外括號會刪除字元類,因此表達式將與提供的確切子字元串匹配。

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