要替换或追加的Bash脚本
我不熟悉Bash脚本,现在有点困难。我正在尝试更改配置文件的配置值。如果它找到一个现有值,我希望它更新它,但如果它不存在,我希望它附加它。这是我从各种在线教程和片段中得到的:要替换或追加的Bash脚本,bash,shell,security,sed,grep,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/
# 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。只需使用命令的返回值,并使用双引号而不是单引号:
if ! sed -i "/$2/{s//$3/;h};"'${x;/./{x;q0};x;q1}' $1
then
echo "$3" >> $1
fi
来源:对于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
=与任何内容匹配的地址/./
=交换保持空间和模式空间-如果成功(保持空间中存在某些内容),则q0=以0状态退出(成功){x;q0}
=交换保持空间和图案空间-由于现在成功(由于上一个x),因此q1=退出,状态为1(失败)x;q1
$2
和$3
。后面部分的单引号可防止错误地替换$
有点复杂,但只要文件中有东西,它似乎就可以工作。空文件仍然会成功,因为在最后一行没有得到任何匹配项
老实说,经历了这么多复杂的事情。。。除非您正在处理的文件非常长,以至于双过程非常糟糕,否则我可能会回到grep
解决方案,如下所示:
if grep -q "^$2" $1
then
sed -i "s/^$2.*$/$3/" $1
else
echo "$3" >>$1
fi
这一点以后更容易理解和维护…变量不会在单引号字符串中展开。获取grep命令的退出代码。@Gumbo我应该将其更改为双引号字符串吗?类似,但不是关于处理配置文件的密切相关帖子,看看这篇文章:如果你愿意,你可以搞乱
grep
,然后在else中执行sed
,但是直接使用sed
的返回值更容易/更快。虽然我同意将其保留在sed中,但不管你是否找到值,sed都会返回相同的值。为此,我认为你需要使用q
标志,但我不知道如何使用它谢谢你非常全面的回答