Answers:
保持简单:)
grep + echo应该足够了:
grep -qxF 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar
-q
安静-x
整行匹配-F
模式是一个普通的字符串编辑:纳入@cerin和@ thijs-wouters建议。
grep -vq ...
echo
触发cat
多行Heredoc进入配置文件。
-s
如果文件不存在,请添加以忽略错误,仅使用该行创建一个新文件。
这是一个干净的,可读的和可重用的解决方案grep
,echo
仅在尚不存在的情况下使用和将行添加到文件中:
LINE='include "/configs/projectname.conf"'
FILE='lighttpd.conf'
grep -qF -- "$LINE" "$FILE" || echo "$LINE" >> "$FILE"
如果您需要匹配整行,请使用 grep -xqF
-s
如果文件不存在,请添加以忽略错误,仅使用该行创建一个新文件。
sudo grep -qF "$LINE" "$FILE" || echo "$LINE" | sudo tee -a "$FILE"
-
。
--
了grep命令,因此它将不再将以破折号开头的$ LINE解释为选项。
这是一个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
sed -i -e '\|session.*pam_mkhomedir.so|h; ${x;s/mkhomedir//;{g;tF};a\' -e 'session\trequired\tpam_mkhomedir.so umask=0022' -e '};:F;s/.*mkhomedir.*/session\trequired\tpam_mkhomedir.so umask=0022/g;' /etc/pam.d/common-session
sed
了很多年,但大部分只是s
命令。该hold
和pattern
空间互换是超越我。
如果有一天,其他人必须将此代码作为“旧版代码”来处理,那么如果您编写的代码不太公开,那么该人将不胜感激,例如
grep -q -F 'include "/configs/projectname.conf"' lighttpd.conf
if [ $? -ne 0 ]; then
echo 'include "/configs/projectname.conf"' >> lighttpd.conf
fi
另一个sed解决方案是始终将其附加在最后一行,并删除现有的。
sed -e '$a\' -e '<your-entry>' -e "/<your-entry-properly-escaped>/d"
“正确转义”表示放置与您的条目匹配的正则表达式,即从实际条目中转义所有正则表达式控件,即在^ $ / *?+()前面加反斜杠。
这可能在文件的最后一行失败,或者如果没有悬空的换行符,我不确定,但是可以通过一些漂亮的分支来解决...
sed -i.bak -e '$a\' -e "$NEW_IP\t\t$HOST.domain\t$HOST" -e "/.*$HOST/d" /etc/hosts
sed -i -e '/<entry>/d; $a <entry>'
d
命令将重新启动sed程序,从而跳过a
ppend。
a
前必须执行ppend 。它与您的原始答案几乎相同。d
sed -i -e '$a<entry>' -e '/<entry>/d'
使用awk
awk 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file file
file file
因为它会使同一文件两次通过。NR==FNR
第一遍是正确的,但第二遍不是。这是常见的Awk习语。
使用grep的答案是错误的。您需要添加-x选项以匹配整行,否则#text to add
在希望精确添加时仍会匹配text to add
。
所以正确的解决方案是这样的:
grep -qxF 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar
使用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可能无法工作,但可以这样工作。但是,如果您要执行此操作,则它不会使您自动化,因为它可能会要求输入密码。
当我尝试从根目录为特定用户进行编辑时遇到问题。仅添加$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
crudini
可能是一个不错的选择(但还不适合lighthttpd)