用于替换或追加的Bash脚本

时间:2015-03-15 12:48:54

标签: bash shell security sed grep

我是Bash脚本新手,我有点困难。我试图改变配置文件的配置值。如果它找到了现有值,我希望它更新它,但如果它不存在,我希望它附加它。这就像我从各种教程和在线片段中得到的那样:

# FUNCTION TO MODIFY CONFIG BY APPEND OR REPLACE
# $1 File
# $2 Find
# $3 Replace / Append
function replaceappend() {
    grep -q '^$2' $1
    sed -i 's/^$2.*/$3/' $1
    echo '$3' >> $1
}

replaceappend "/etc/test.conf" "Port 20" "Port 10"

然而,正如您可能想象的那样,这并不起作用。它似乎与它背后的逻辑有关,我不确定如何捕获grep的结果以选择sed或echo。

1 个答案:

答案 0 :(得分:2)

只需使用命令的返回值,并使用双引号而不是单引号:

if ! sed -i "/$2/{s//$3/;h};"'${x;/./{x;q0};x;q1}' $1
then
    echo "$3" >> $1
fi

SOURCE:Return code of sed for no match用于q命令

这是在我正常使用sed之外的问题,所以让我解释一下这是如何工作的,正如我所理解的那样:

sed "/$2/{s//$3/;h};"'${x;/./{x;q0};x;q1}' $1

第一个/$2/是一个地址 - 我们将在{...}内为与此匹配的任何行执行命令。作为副产品,它还将模式空间设置为$2

命令{s//$3/;h}表示用$3替换模式空间中的任何内容,然后将模式空间保存在“保持空间”中,这是sed中的一种缓冲区。

单引号后的$是另一个地址 - 它说要在最后一行执行下一个命令。

命令{x;/./{x;q0};x;q1}说:

  • x =交换保留空间和模式空间
  • /./ =匹配任何内容的地址
  • {x;q0} =交换保持空间和模式空间 - 如果成功(保留空间中存在某些内容)则q0 =退出状态为0(成功)
  • x;q1 =交换保留空间和模式空间 - 因为现在成功(由于前面的x),然后q1 =退出1状态(失败)

第一部分的双引号允许替换$2$3。后一部分的单引号可防止错误地替换$

有点复杂,但它似乎很长,因为你已经在文件中存在了一些东西。由于您在最后一行没有得到任何匹配,因此空文件仍然会成功。

老实说,在所有这些复杂问题之后......除非您正在使用的文件非常长,以至于双通非常糟糕,我可能会回到这样的grep解决方案:

if grep -q "^$2" $1
then
    sed -i "s/^$2.*$/$3/" $1
else
    echo "$3" >>$1
fi

以后更容易理解和维护这一点......