0

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:

  1. how-to-add-a-line-in-sed-if-not-match-is-found

  2. sed-command-how-to-replace-if-exists-else-just-insert

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 ?

Community
  • 1
  • 1
hDan
  • 467
  • 4
  • 19

1 Answers1

3

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'
123
  • 10,778
  • 2
  • 22
  • 45
  • 1
    Your solution works fine, but if the search pattern is not found it delets the last line and appends the replace pattern. – hDan Feb 22 '16 at 11:14
  • @mUncescu Fixed, it didn't delete it, i forgot to exchange it back in. – 123 Feb 22 '16 at 11:17
  • My +1 for awk solution, `sed` is not the best tool for this I believe :) – anubhava Feb 22 '16 at 11:24
  • I have one issue. Your awk solution prints the action, can you update it to also modify the file ? – hDan Feb 22 '16 at 12:16
  • @mUncescu Work it out, it isn't very difficult. A simple google search will tell you how. – 123 Feb 22 '16 at 13:18
  • With sed is simple, I can use inline replacement. But for awk you don't have this option, there is for gawk, with -i inplace, but if the search pattern is not found, it prints the added line on the screen. I did find an option with creating a temporary file and moving the temp to the file. But I don't wan't to use a temp file. – hDan Feb 22 '16 at 13:38
  • @mUncescu You have to use a tmp file if you can't use inplace, although i can't see why it would print to screen... – 123 Feb 22 '16 at 13:47