Reputation: 467
I am using FreeBSD, I have a config file, and I need an one liner, without pipe, to find a particular string, if found replace, if not append to end of file.
I looked over different options, like, not works ok:
This is what I have to work almost ok:
gsed -r 's/search/replace/; t; $areplace' 'app.conf'
The problem I have is that the t
command is not working as expected. Because if I have the string "search" inside the file, it does the replacement, but it also appends. If the "search" string is the last in the file, it does the replacement, and it doesn't append.
EDIT - Added Sample
Sample input:
ssh_enable="yes"
snmpd_enable="YES"
dumpdev="AUTO"
Sample command:
gsed -r 's/.*snmpd_enable=\".*\".*/snmpd_enable=\"NO\"/; t; $asnmpd_enable=\"NO\"/' 'app.conf'
Expected output:
ssh_enable="yes"
snmpd_enable="NO"
dumpdev="AUTO"
Actual output:
ssh_enable="yes"
snmpd_enable="NO"
dumpdev="AUTO"
snmpd_enable="NO"
EDIT - Solution
I ended up using @123 solution,
gawk -i inplace '{x+=sub(/search/,"replace")}END{if(!x)print "replace"}1'
But the issue here is that if the file does not contain the search string, it will print replace. Any ideeas ?
Upvotes: 0
Views: 982
Reputation: 11226
With gsed
sed 's/search/replace/;t1;/$^/{:1;H};${x;/./!{x;s/$/\nreplace/;b};x}' file
With awk
awk '{x+=sub(/search/,"replace")}END{if(!x)print "replace"}1' file
With your actual data
sed '/^snmpd_enable=/{s/="[^"]*"/="NO"/;H};${x;/./!{x;s/$/\nsnmpd_enable="NO"/;b};x}'
awk '/^snmpd_enable=/{x+=sub(/"[^"]*"/,"\"NO\"")}END{if(!x)print "snmpd_enable=\"NO\""}1'
Upvotes: 3