I am having a little trouble trying to do a search and replace using sed in a config file.

I want to use multiple commands using the -e option to do the following.

  • Step 1: find the first occurrence of DBName=.* in the file at the start of a line and replace with DBName=localhost
  • If DBName=.* does not exist
    • Step 2: find the first occurrence of # DBNAME=.* in the file at the start of a line and insert a line below the string with DBName=localhost
  • If # DBNAME=.* does not exist
    • Step 3: insert DBName=localhost at the bottom of the file

The first occurrence syntax is tripping me up. Also the # followed by a "space" in the string # DBNAME= is also catching me out.

  • If a line starts with DBName= then DBName=.* matches the entire line so replacing DBName=.* with DBName=localhost means replacing the entire line. Is that what you want ? – don_crissti Sep 9 '15 at 7:08
  • @don_crissti, Yes that is what I am after. Step 1 will look something like this sed -i -e 's/DBName=.*/DBName=localhost/' FILENAME but I want it to only do this for the 1st occurance. It is unlikely that there will be more than one occurrence of this string without a preceding # but I want to make my bash script foolproof. – ausip Sep 9 '15 at 7:21
  • Furthermore, if your file contains both DBName=.* and # DBNAME=.* does the first occurrence of DBName=.* always precede the first occurrence of # DBNAME=.* ? Please add this information to your post too. – don_crissti Sep 9 '15 at 7:48

Use this:

sed -e '/^DBName=.*/{s/^DBName=.*/DBName=localhost/;:a;n;ba;q}' \
  -e '/^# DBName=.*/{a \DBName=localhost
  :a;n;ba;q}' -e '$a \DBName=localhost' file


  • The first -e statement searches for ^DBName=.* (^ means from the beginning of the line) and if it is found, the part in the {} brachets is executed: This will search and replace the strings and when done, :a sets a label called a, n reads the next line in the pattern space and prints it. ba goes back to the label a. This all causes sed to print all remaining lines untouched. Now sed exits with the q command at this point and the other expressions will not be processed. So the replacement is done only once.
  • The second expression searches for lines beginning with # DBName=.* and if found a adds DBName=localhost to the next line. Notice, the newline here in the command is needed, because the a command must not have anything after it on its line. When that addition is done, :a;n;ba;q does the same as in the first expression. If not...
  • ...the third expression is processed. It adds to the last line of the file ($) with the a command the string DBName=localhost.
| improve this answer | |
  • Thanks, that looks like it will work a treat. Although, how do I tell each expression to only do this for the first string found in the file? – ausip Sep 9 '15 at 7:49
  • @ausip Sorry now it should work as expected. Please try again. – chaos Sep 9 '15 at 8:53
sed -i 's/DBName=.\*/DBName=localhost/g' -e 's/\# DBNAME=.*/DBName=localhost/g' config_file

It will satisfy your first two conditions

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.