我是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。
答案 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
以后更容易理解和维护这一点......