我需要在配置文件的末尾添加以下一行:
include "/configs/projectname.conf"
到一个名为lighttpd.conf的文件
我正在研究使用sed来做到这一点,但我不知道如何。
我怎么能只插入它,如果行已经不存在?
我需要在配置文件的末尾添加以下一行:
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 "
Try:
LINE='include "/configs/projectname.conf"'
sed -n "\|$LINE|q;\$a $LINE" lighttpd.conf >> lighttpd.conf
使用管道作为分隔符,如果找到$LINE则退出。否则,在结尾附加$LINE。
因为我们只在sed命令中读取文件,所以我认为我们一般不存在clobber问题(这取决于您的shell设置)。
下面是一个单行sed,它内联完成这项工作。注意,当变量存在时,它会保留变量的位置及其在文件中的缩进。这对于上下文来说通常很重要,比如当周围有注释时,或者当变量位于缩进块中时。任何基于“先删除再追加”范式的解决方案在这方面都失败得很厉害。
sed -i '/^[ \t]*option=/{h;s/=.*/=value/};${x;/^$/{s//option=value/;H};x}' test.conf
对于一个通用的变量/值对,你可以这样写:
var=c
val='12 34' # it handles spaces nicely btw
sed -i '/^[ \t]*'"$var"'=/{h;s/=.*/='"$val"'/};${x;/^$/{s//c='"$val"'/;H};x}' test.conf
最后,如果还想保留内联注释,可以使用catch组。例如,如果test.conf包含以下内容:
a=123
# Here is "c":
c=999 # with its own comment and indent
b=234
d=567
然后运行这个
var='c'
val='"yay"'
sed -i '/^[ \t]*'"$var"'=/{h;s/=[^#]*\(.*\)/='"$val"'\1/;s/'"$val"'#/'"$val"' #/};${x;/^$/{s//'"$var"'='"$val"'/;H};x}' test.conf
生产:
a=123
# Here is "c":
c="yay" # with its own comment and indent
b=234
d=567
作为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程序中只需要一个空格,即打印后的空格。 如果文件包含#注释,它们将被保留。
使用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
在root下使用echo可能不起作用,但可以像这样工作。但它不会让你自动化的事情,如果你想这样做,因为它可能会要求密码。
当我试图为特定用户从根目录进行编辑时,遇到了一个问题。只是添加$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