我使用下面的命令sed
在配置文件來替換一些參數如何在SED添加一行:如果沒有找到匹配
sed -i 's/^option.*/option=value/g' /etc/fdm_monitor.conf
現在我有一個問題。如果該行不存在,我想將其添加到文件的底部。
我打電話給一個popen
出C程序。我嘗試使用awk
。
我使用下面的命令sed
在配置文件來替換一些參數如何在SED添加一行:如果沒有找到匹配
sed -i 's/^option.*/option=value/g' /etc/fdm_monitor.conf
現在我有一個問題。如果該行不存在,我想將其添加到文件的底部。
我打電話給一個popen
出C程序。我嘗試使用awk
。
試試這個:
grep -q '^option' file && sed -i 's/^option.*/option=value/' file || echo 'option=value' >> file
這是它使用
awk -f update.awk </etc/fdm_monitor.conf> /etc/fdm_monitor.conf.tmp && \
mv /etc/fdm_monitor.conf.tmp /etc/fdm_monitor.conf
或
awk -f update.awk < /etc/fdm_monitor.conf | sponge /etc/fdm_monitor.conf
/^option *=/ {
print "option=value"; # print this instead of the original line
done=1; # set a flag, that the line was found
next # all done for this line
}
{print} # all other lines -> print them
END { # end of file
if(done != 1) # haven't found /option=/ -> add it at the end of output
print "option=value"
}
運行的awk
執行編輯: 作爲一個班輪:
awk '/^option *=/ {print "option=value";d=1;next}{print}END{if(d!=1)print "option=value"}' /etc/fdm_monitor.conf | sponge /etc/fdm_monitor.conf
我需要一個襯墊,因爲我送這是從C PROGRAMM系統調用。 – Evilmachine
這裏是一個awk的一行:
awk -v s="option=value" '/^option/{f=1;$0=s}7;END{if(!f)print s}' file
這並不做就地更改文件,但是,您可以:
awk '...' file > tmpfile && mv tmpfile file
使用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
這似乎並不奏效。它在每行之後添加「option = value」。不知道它是如何得到兩個upvotes。你可以做'$ aoption = value',但是我似乎無法在前一個匹配項上做出這樣的條件,所以無論如何它只是追加到最後。 – sosiouxme
sed -i '1 h
1 !H
$ {
x
s/^option.*/option=value/g
t
s/$/\
option=value/
}' /etc/fdm_monitor.conf
負荷都在緩衝區中的文件,到了最後,將所有發生和如果沒有變化發生時,添加到末尾
sed -i 's/^option.*/option=value/g' /etc/fdm_monitor.conf
grep -q "option=value" /etc/fdm_monitor.conf || echo "option=value" >> /etc/fdm_monitor.conf
作爲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]是您的輸入file
。它被打開並寫入END
塊的for
循環中。在END
塊中輸出file
代替了對諸如sponge
之類的實用程序的需求,或者寫入臨時文件,然後將臨時文件寫入file
。
數組a[]
的兩個賦值將所有輸出行累加到a
。if(!f)a[++n]=s
如果主awk循環在file
中找不到option
,則附加新的option=value
。
爲了便於閱讀,我添加了一些空格(不是很多),但是在整個awk程序中只需要一個空格,即print
之後的空格。 如果file
包括# comments
它們將被保留。
我通過設置變量來闡述kev的grep/sed解決方案,以減少重複。
在第一行設置變量(提示:$_option
應匹配行中的所有內容,直到值[包括任何分隔符= =或]:]。
_file="/etc/ssmtp/ssmtp.conf" _option="mailhub=" _value="my.domain.tld" \ sh -c '\ grep -q "^$_option" "$_file" \ && sed -i "s/^$_option.*/$_option$_value/" "$_file" \ || echo "$_option$_value" >> "$_file"\ '
記住,sh -c '...'
只是有擴大變量的作用域,而不需要一個export
的效果。 (見Setting an environment variable before a command in bash not working for second command in a pipe)
這裏是一個內聯的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
非常容易和有用! – JohnyTex