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

include "/configs/projectname.conf"

到一个名为lighttpd.conf的文件

我正在研究使用sed来做到这一点,但我不知道如何。

我怎么能只插入它,如果行已经不存在?


当前回答

使用sed,你可以这样说:

sed -e '/option=/{s/.*/option=value/;:a;n;:ba;q}' -e 'aoption=value' filename

如果参数存在,这将替换它,否则将把它添加到文件的底部。


如果你想就地编辑文件,使用-i选项:

sed -i -e '/option=/{s/.*/option=value/;:a;n;:ba;q}' -e 'aoption=value' filename

其他回答

只使用sed,我建议使用以下解决方案:

sed -i \
    -e 's#^include "/configs/projectname.conf"#include "/configs/projectname.conf"#' \
    -e t \
    -e '$ainclude "/configs/projectname.conf"' lighttpd.conf

将include“/configs/projectname.conf”行替换为自身(此处使用#作为分隔符)

T如果替换成功,跳过其余命令

$a否则跳转到最后一行,并在其后添加include "/configs/projectname.conf "

几乎所有的答案都有效,但根据我的经验,并不是在所有场景或操作系统中都有效。以下是唯一适用于旧系统和新的不同口味的操作系统的东西。 我需要附加KUBECONFIG路径到bashrc文件,如果它不存在。我所做的是

我假设它存在,然后删除它。 使用sed附加我想要的字符串。

sed -i '/KUBECONFIG=/d' ~/.bashrc

echo 'export KUBECONFIG=/etc/rancher/rke2/rke2.yaml' >> ~/.bashrc

作为awk专用的一行代码:

awk -v s=option=value '/^option=/{$0=s;f=1} {a[++n]=$0} END{if(!f)a[++n]=s;for(i=1;i<=n;i++)print a[i]>ARGV[1]}' file

ARGV[1]是你的输入文件。它被打开并写入end块的for循环中。在END块中打开文件进行输出,取代了像海绵或写入临时文件,然后将临时文件移动到文件等实用程序的需要。

对数组a[]的两次赋值将所有输出行累加到a中。if(!f)a[++n]=s如果主awk循环在文件中找不到option,则追加新的option=value。

为了可读性,我添加了一些空格(不是很多),但在整个awk程序中只需要一个空格,即打印后的空格。 如果文件包含#注释,它们将被保留。

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

import os,sys
LINE = 'include '+ <insert_line_STRING>
FILE = <insert_file_path_STRING>                                
os.system('grep -qxF $"'+LINE+'" '+FILE+' || echo $"'+LINE+'" >> '+FILE)

$和双重报价让我陷入了困境,但这奏效了。 谢谢大家

保持简单就好:)

Grep + echo就足够了:

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

-q安静点 -x匹配整行 -F pattern是一个普通字符串 https://linux.die.net/man/1/grep

编辑: 合并了@cerin和@thijs-wouters的建议。