在别名函数中正确替换变量

在别名函数中正确替换变量

我正在尝试创建一个别名函数来从文件中删除输入的行:

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

这使得该函数充当过滤器只做罐头上所说的,即,它从输入中删除行,并且不关心输入来自何处或去向何处。

相关内容