2010-08-24 48 views

回答

160

只要保持它的簡單:)

grep的 + 呼應應該足夠了:

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

編輯: 納入@Cerin建議

的「編輯」改變我的回答:如果你有一個替代的解決方案給你自己的答案!編輯旨在澄清,格式化,更好的英語等!不要改變別人給出的答案! (謝謝)

+0

這人做什麼,我需要的相反。如果該行已經存在,它只會將該行添加到文件中。如果它不存在,我只想添加它。有任何想法嗎? – 2010-08-24 15:56:33

+0

對不起,遺忘了一個「-v」選項來grep,或用||替換&&。 :) 我要更正,謝謝 – drAlberT 2010-08-24 16:27:04

+2

我會添加-q開關到grep來壓制輸出:'grep -vq ...' – 2010-08-24 16:33:01

3

用awk

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

它是'文件文件'還是'文件'? – webdevguy 2014-04-29 13:48:30

+0

它是'文件文件',因爲它在同一個文件上做了兩遍。 「NR == FNR」在第一次傳球中是正確的,但不是第二次傳球。這是一個常見的Awk成語。 – tripleee 2017-03-15 14:12:11

11

這裏有一個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 
+0

對於用完整/更新的配置文件條目替換部分字符串的命令,或者根據需要追加行:'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' – bgStack15 2016-05-31 16:01:35

+0

不錯,它幫了我很多+1。你能否解釋你的sed表達? – Rahul 2016-06-10 10:39:14

+0

我很想看到這個解決方案的註釋說明。我已經使用了'sed'多年,但主要是's'命令。 'hold'和'pattern'空間互換已經超出了我的想象。 – nortally 2016-06-24 15:50:57

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 
+0

這看起來不正確,當配置行丟失時,它將丟失文件中的其他行。 – tripleee 2017-03-15 14:13:45

1

另一個sed的解決辦法是要始終將其追加的最後一行,並刪除預先存在的一個。

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

「正確轉義」是指把符合您進入一個正則表達式,即從你的實際工作進入逃避所有的正則表達式controlls,即把一個反斜槓盈的^ $/*?+()。

這可能會失敗在你的文件的最後一行或如果沒有纏繞換行,我不知道,但可能是作了妥善處理一些漂亮的分支...

42

這將是一個乾淨,可讀和可重用使用grepecho添加一行到,只有當它尚不文件的解決方案存在:

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

如果是需要root權限的文件:'sudo grep -qF「$ LINE」「$ FILE」||回聲「$ LINE」| sudo tee -a「$ FILE」' – nebffa 2017-12-08 00:50:46

+0

當這行以'-'開始時,這實際上不起作用。 – zsero 2018-02-06 22:03:46

+0

@zsero:好點!我在grep命令中加了'--',所以它不會再以破折號開頭解釋$ LINE。 – rubo77 2018-02-07 01:05:33

5

如果要寫入受保護的文件,@drAlberT和@ rubo77的答案可能不適合工作你既然不能sudo >>。一個similarly simple solution,那麼,是使用tee --append

LINE='include "/configs/projectname.conf"' 
FILE=lighttpd.conf 
grep -qF "$LINE" "$FILE" || echo "$LINE" | sudo tee --append "$FILE" 
相關問題