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

include "/configs/projectname.conf"

到一个名为lighttpd.conf的文件

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

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


当前回答

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

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

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

其他回答

sed -i '1 h
1 !H
$ {
   x
   s/^option.*/option=value/g
   t
   s/$/\
option=value/
   }' /etc/fdm_monitor.conf

加载缓冲区中的所有文件,在结束时,更改所有发生的情况,如果没有发生变化,则添加到结束

下面是一个单行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 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file file

这将是一个干净、易读和可重用的解决方案,使用grep和echo仅在文件不存在时才向文件添加一行:

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

如果需要匹配整行,请使用grep -xqF

添加-s来忽略文件不存在时的错误,用这一行创建一个新文件。

我需要编辑一个文件限制写权限,所以需要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