Replace or add a string to a file

38,950

Solution 1

One way to do this it to bring grep into the equation. First check whether the file contains the string with a quick grep and then append or substitute accordingly:

grep -q string file && 
    sed -i 's/string/newstring/' file || echo "newstring" >> file

The above is a shorthand way of writing:

if grep -q string file; then 
    sed -i 's/string/newstring/' file
else
    echo "newstring" >> file
fi

Personally, however, I would use perl for this instead. Just read the file once and set a variable to 1 if the substitution was made. Then, at the end, add the string if the variable is not 1:

perl -lpe '$i=1 if s/oldstring/newstring/; 
           END{print "newstring" if $i!=1;}' file > tmpfile && mv tmpfile file

Solution 2

This should achieve what is required:

grep -q "oldstring" test.txt
if [ $? -eq 1 ]; then
    echo "newstring" >> test.txt
else
    sed -i 's/oldstring/newstring/g' test.txt
fi

Solution 3

Using AWK:

<<<"$(<in)" awk '{if(/foo/){x=sub(/foo/, "bar", $0)};print}END{if(x!=1){print "bar"}}' >in
% cat in1
string oldstring string
% cat in2
string foo string
% <<<"$(<in1)" awk '{if(/oldstring/){x=sub(/oldstring/, "newstring", $0)};print}END{if(x!=1){print "newstring"}}' >in1
user@user-X550CL ~/tmp % cat in1
string newstring string
% <<<"$(<in2)" awk '{if(/oldstring/){x=sub(/oldstring/, "newstring", $0)};print}END{if(x!=1){print "newstring"}}' >in2
% cat in2
string foo string
newstring
Share:
38,950

Related videos on Youtube

Josh
Author by

Josh

Updated on September 18, 2022

Comments

  • Josh
    Josh over 1 year

    I know sed can replace a piece of string within a text file like this :

    sed -i 's/oldstring/newstring/g' test.txt
    

    But, how do I replace the line if it exists and automatically add it on a new line if it doesn't exist?

    Thanks.

    Edit : Thank you for your responses. As per the requests on your comments and answer, here's more details :

    • I want to check the existence of the old string and replace it with the new string if it exists.
    • I want to add the new string in a new line at the end of the txt file if the old string does not exist
    • If there are multiple occurances of the same string, it would be an error since its a config file.The other occurances can be removed after replacing the first occurance.
    • Admin
      Admin over 8 years
      Add it in a new line where? At the end of the doc?
    • Admin
      Admin over 8 years
      Check existence of old or new string or both? Add old or new string?
  • Sadi
    Sadi over 8 years
    @kos : Thank you for the UUOC award ( : - D ) and for taking the time to teach something to this beginner in shell scripting. I'll now try to improve the code above.
  • kos
    kos over 8 years
    I didn't really mean to "award" it to you, just to point that out. :D. Looks better, you could also shorten the if / else check to this single line: [ $? -eq 1 ] && echo "newstring" >> test.txt || sed -i 's/oldstring/newstring/g' test.txt.
  • terdon
    terdon over 8 years
    @kos yes, the END{} is executed after the file has been closed so it won't work.
  • Sadi
    Sadi over 8 years
    Thanks for the nice shorthand, but wouldn't it be better to use printf "\nnewstring" as echo "newstring" seems to append it to the last (non-empty) line? On the other hand, using printf "\n..." leaves an empty line above when there's already an empty line at the end. Any better solution for this?
  • terdon
    terdon over 8 years
    @Sadi no, echo foo >> file will add foo in a new line. So will printf 'foo\n' >> file.
  • terdon
    terdon over 8 years
    @Sadi that's different. The >> operator appends to the end of the file. Normally, the last character of a text file is \n so it will append the text after the \n and make a new line. If you know your file doesn't end with a \n, you would have to use printf '\nfoo\n' >> file, yes. If you need to deal with such cases, please edit your question and make it clear.