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

时间:2010-08-24 13:40:19

标签: linux sed terminal

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

include "/configs/projectname.conf"

到名为lighttpd.conf

的文件

我正在考虑使用sed来执行此操作,但我无法确定如何使用。

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

12 个答案:

答案 0 :(得分:217)

保持简单:)

grep + echo 应该足够了:

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

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

答案 1 :(得分:63)

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

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

答案 2 :(得分: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

答案 3 :(得分:7)

如果写入受保护的文件,@ drAlberT和@rubo77的答案可能对你不起作用,因为人们不能{@ 1}}。那么similarly simple solution就是使用>>

tee --append

答案 4 :(得分:7)

如果有一天,其他人将此代码作为"遗留代码"处理,那么如果你写一个不太开放的代码,例如

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

答案 5 :(得分:5)

另一个sed解决方案是始终将它附加在最后一行并删除一个现有的。

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

&#34;妥转义&#34;意味着放置一个与你的条目匹配的正则表达式,即从你的实际条目中转义所有正则表达式控件,即在$ $ / *?+()前面放一个反斜杠。

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

答案 6 :(得分:3)

使用awk

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

答案 7 :(得分:1)

使用grep的答案是错误的。您需要添加-x选项以匹配整行,否则,当希望完全添加#text to add时,像text to add这样的行仍然会匹配。

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

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

答案 8 :(得分: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

使用单线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

答案 9 :(得分: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

答案 10 :(得分:0)

我为此创建了一个经过战斗测试的脚本,称为contains.sh

用法: ./contains.sh PATTERN [ADDITION [USER]]

示例:

./contains.sh /etc/lighttpd/lighttpd.conf \
    \"include\s+\"/configs/projectname.conf\"" \
    "include \"/configs/projectname.conf\"" root

此命令在保留文件许可权和所有权的同时进行原子写入。您无需以root用户身份运行它(仅在需要时使用sudo)。即使文件没有以换行符结尾,它也可以确保整齐地附加行。仅运行./contains.sh,以获取更多帮助和示例。

答案 11 :(得分:0)

如果您想在 Linux 终端中使用 python 脚本运行此命令...

use v5.20;
my %larger = %hash2{ @larger_keys };

$ 和双引号让我陷入了困境,但这奏效了。 谢谢大家