仅当文件尚不存在时才在文件中附加一行

问题描述 投票:119回答:10

我需要在配置文件的末尾添加以下行:

include "/configs/projectname.conf"

到一个名为lighttpd.conf的文件

我正在考虑使用sed这样做,但我无法弄清楚如何。

如果该行尚不存在,我将如何仅插入它?

linux sed terminal
10个回答
222
投票

保持简单:)

grep + echo应该足够了:

grep -qxF 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar

编辑:纳入@cerin和@thijs-wouters建议。


0
投票

我需要编辑具有受限写入权限的文件,因此需要sudo。使用ghostdog74的答案并使用临时文件:

awk 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file > /tmp/file
sudo mv /tmp/file file

65
投票

这将是一个干净,可读和可重用的解决方案,使用grepecho只有在文件尚不存在的情况下才能添加一行:

LINE='include "/configs/projectname.conf"'
FILE='lighttpd.conf'
grep -qF -- "$LINE" "$FILE" || echo "$LINE" >> "$FILE"

12
投票

这是一个sed版本:

sed -e '\|include "/configs/projectname.conf"|h; ${x;s/incl//;{g;t};a\' -e 'include "/configs/projectname.conf"' -e '}' file

如果您的字符串在变量中:

string='include "/configs/projectname.conf"'
sed -e "\|$string|h; \${x;s|$string||;{g;t};a\\" -e "$string" -e "}" file

7
投票

如果写入受保护的文件,@ drAlberT和@rubo77的答案可能不适合你,因为一个人不能sudo >>。那么,similarly simple solution将使用tee --append

LINE='include "/configs/projectname.conf"'
FILE=lighttpd.conf
grep -qF "$LINE" "$FILE"  || echo "$LINE" | sudo tee --append "$FILE"

7
投票

如果有一天,其他人必须将此代码作为“遗留代码”来处理,那么如果您编写一个不那么开放的代码,那么该人将不胜感激,例如

grep -q -F 'include "/configs/projectname.conf"' lighttpd.conf
if [ $? -ne 0 ]; then
  echo 'include "/configs/projectname.conf"' >> lighttpd.conf
fi

5
投票

另一种解决方案是始终将其附加到最后一行并删除预先存在的一行。

sed -e '$a\' -e '<your-entry>' -e "/<your-entry-properly-escaped>/d"

“正确转义”意味着放置一个与你的条目匹配的正则表达式,即从你的实际条目中转义所有正则表达式控制,即在^ $ / *?+()前面加一个反斜杠。

这可能会在你的文件的最后一行失败,或者如果没有纠结的换行符,我不确定,但这可以通过一些漂亮的分支来处理......


3
投票

使用awk

awk 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file file

1
投票

使用grep的答案是错误的。你需要添加一个-x选项来匹配整行,否则像#text to add这样的行在寻找完全添加text to add时仍会匹配。

所以正确的解决方案是这样的:

grep -qxF 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar

1
投票

使用sed:它将插入行尾。您也可以照常传递变量。

grep -qxF "port=9033" $light.conf
if [ $? -ne 0 ]; then
  sed -i "$ a port=9033" $light.conf
else
    echo "port=9033 already added"
fi

使用oneliner sed

grep -qxF "port=9033" $lightconf || sed -i "$ a port=9033" $lightconf

使用echo可能无法在root下工作,但会像这样工作。但是如果你想要这样做,它不会让你自动化,因为它可能会要求输入密码。

当我尝试从特定用户的根编辑时遇到问题。刚刚添加$username对我来说是一个修复。

grep -qxF "port=9033" light.conf
if [ $? -ne 0 ]; then
  sudo -u $user_name echo "port=9033" >> light.conf
else
    echo "already there"    
fi
© www.soinside.com 2019 - 2024. All rights reserved.