skip to Main Content

I want to replace 2 same words in file(app.properties) with 2 different words using sed command.
Example:

mysql.host=<<CHANGE_ME>>
mysql.username=testuser
mysql.port=3306
mysql.db.password=<<CHANGE_ME>>

required output will be

mysql.host=localhost
mysql.username=testuser
mysql.port=3306
mysql.db.password=password123

I tried below command:

sed -e "s/<<CHANGE_ME>>/localhost/1" -e "s/<<CHANGE_ME>>/password123/2" app.properties > /home/centos/SCRIPT/io.properties_new

However I am getting localhost at both the places.

4

Answers


  1. This may be possible but I don’t know if this is really readable for everyone.
    Something like this might suite you :

    sed -e '0,/<<CHANGE_ME>>/{s/<<CHANGE_ME>>/localhost/}' -e '1,/<<CHANGE_ME>>/{s/<<CHANGE_ME>>/password123/}' app.properties > /home/centos/SCRIPT/io.properties_new
    

    If you have any idea to improve this, don’t hesitate. I would really like to learn the best way to do this too 😀

    Login or Signup to reply.
  2. I’m sure it’s not impossible, but also that you will not be able to figure out how it works once you find an answer. A better solution is to switch to a language which is more human-readable, so you can understand what it does.

    awk 'BEGIN { split("localhost:password123", items, ":") }
        /<<CHANGE_ME>>/ { sub(/<<CHANGE_ME>>/, items[++i]) } 1' input_file >output_file
    

    The BEGIN block creates an array items of replacements. The main script then increments i every time we perform a replacement, indexing further into items for the replacement string.

    Login or Signup to reply.
  3. Perhaps this might help:

    sed -e '1s/<<CHANGE_ME>>/localhost/' 
        -e '4s/<<CHANGE_ME>>/password123/' 
          app.properties > /home/centos/SCRIPT/io.properties_new
    
    Login or Signup to reply.
  4. With sed, using a wonderfully confusing if (first time) do x, else do y logic:

    sed '/<CHANGE_ME>/{bb;:a;s/<CHANGE_ME>/password123/;:b;x;s/E//;x;ta;s/<CHANGE_ME>/localhost/;x;s/^/E/;x}' input_file
    

    Writing each command of the sed script on its own line makes it more understandable, or at least easier for me to expain it:

    /<CHANGE_ME>/{
      bb
      :a
      s/<CHANGE_ME>/password123/
      :b
      x
      s/E//
      x
      ta
      s/<CHANGE_ME>/localhost/
      x
      s/^/E/
      x
    }
    

    Here’s the explanation:

    • /<CHANGE_ME>/{…} means that the stuff in {…} is only applied to lines matching <CHANGE_ME>;
    1. bb: "branch to (go to) :b", in this case used to skip the first substitution command;
    2. :a: a target for another branch or test-and-branch command;
    3. s/…/…/: you know what it does, but we skip this the first time the script is run;
    4. b: branches to the end of the script, skipping everything (because we are giving no argument to b);
    5. :b: the target of the command bb at 1.;
    6. x: swap patter space (the line you’re dealing with at the moment), with the hold space (a kind of variable that you can put stuff into via x, h, and H commands);
    7. s/E//: tries to match and delete a E (just because that’s the initial of my name), which fails the first time we run this, because the hold space that we’ve swapped earlier with the patter space was empty;
    8. x: undos what the previous x did, so we’re back on working with the line matching <CHANGE_ME>;
    9. ta: tests if last peformed s/…/…/ command succeeded and, if so, it goes to :a, otherwise it’s a no-op; the first time we run the script this is a no-op, because step 6 failed;
    10. s/…/…/: you know what it does;
    11. x: see above
    12. s/^/E/: inserts the E at the beginning of the line, so that next time we run the script substitution of step 7 succeedes, step 9 successfully branches to :a, step 3 is peformed for the first time, and step 4 exits the script for ever;
    13. x: see above
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search