在別名函數中正確替換變數

在別名函數中正確替換變數

我正在嘗試創建一個別名函數來從文件中刪除輸入的行:

function remove_line(){
       line_to_remove="'s/^"$1"$//g'"
       sed -i $(line_to_remove) my_file
}

例如: remove_line domain.com應該從給定檔案中刪除該網域。

然而,似乎$沒有正確解釋。我究竟做錯了什麼?

答案1

你的主要問題$(line_to_remove)命令替換,即用括號內的命令輸出的文字替換的表達式(line_to_remove我希望這會給您一個“命令未找到”錯誤)。您可能想使用"$line_to_remove"它。

但是,將 shell 變數注入到sed替換表達式中並不理想,因為它對注入的字串設定了太多條件(它必須是有效的正規表示式並且不能包含/等)

相反,我建議使用grep並將結果寫入標準輸出或寫入臨時文件,在成功執行 後替換原始文件grep,或者您可以讓sponge(來自 GNU moreutils 包)覆蓋原始文件。

remove_lines () {
       grep -v -Fx -e "$1" my_file | sponge my_file
}

此處使用的選項可grep確保作為函數的第一個參數給出的行按原樣使用(而不是作為正則表達式),從頭到尾匹配行,並從輸入中刪除匹配的行。

沒有sponge

remove_lines () {
       tmpfile=$(mktemp)
       grep -v -Fx -e "$1" my_file >"$tmpfile" && mv "$tmpfile" my_file
       rm -f "$tmpfile"
}

mv僅當成功執行時才會執行,grep如果rm -f未成功執行則刪除臨時檔案。


就我個人而言,我可能會這樣寫函數:

remove_lines () {
       grep -v -Fx -e "$1"
}

這允許用戶像這樣使用它:

remove_lines "my line" <my_file | sponge my_file

some-command | remove_lines "bumble bee" | other-command

這使得該函數充當過濾器只做罐頭上所說的,即,它從輸入中刪除行,並且不關心輸入來自何處或去向何處。

相關內容