30

On Linux sed -i will modify the input files in place. It doesn't work on Solaris, though.

sed -i '$ s/OLD/NEW/g' test        
sed: illegal option -- i

What can I use in place of sed -i on Solaris?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
lidia
  • 3,043
  • 14
  • 42
  • 47
  • *On Linux `sed -i` will modify the input files in place.* Not really - [GNU `sed -i` creates a new temp file and then renames it to the original file name, deleting the original file in the process.](https://stackoverflow.com/questions/12696125/sed-edit-file-in-place) – Andrew Henle Jun 02 '20 at 03:32

3 Answers3

26

It isn't exactly the same as sed -i, but i had a similar issue. You can do this using perl:

perl -pi -e 's/find/replace/g' file

doing the copy/move only works for single files. if you want to replace some text across every file in a directory and sub-directories, you need something which does it in place. you can do this with perl and find:

find . -exec perl -pi -e 's/find/replace/g' '{}' \;
Charlie B
  • 525
  • 4
  • 6
  • doesn't work well when the string being found/replaced contains slashes and single quotes. tried escaping those characters with no luck. – FanDeLaU Mar 18 '19 at 18:22
  • The complete answer is, it works with GNU sed. You could install GNU sed in Solaris and enjoy. If not possible, a way to make it work with Solaris sed is: `( rm -f myfile ; sed 's/../../' > myfile) < myfile`. _Credit: http://board.issociate.de/thread/460042/_ – FanDeLaU Nov 15 '19 at 20:20
  • which is a different way of implement John's solution above. ^_^ – FanDeLaU Nov 15 '19 at 20:27
21

You'll need to replicate -i's behavior yourself by storing the results in a temp file and then replacing the original file with the temp file. This may seem inelegant but that's all sed -i is doing under the covers.

sed '$ s/OLD/NEW/g' test > test.tmp && cat test.tmp > test && rm test.tmp

If you care you could make it a bit more robust by using mktemp:

tmp=$(mktemp test.XXXXXX)
sed '$ s/OLD/NEW/g' test > "$tmp" && cat "$tmp" > test && rm "$tmp"
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • 1
    Alternatively, copy the original to temp file, redirect the command to overwrite the original (reinstate if the command fails), then remove the copy. – Toby Speight Dec 06 '18 at 12:52
-1

One more "one-line" command which works on Solaris 11 host in bash enviroment:

for i in `cat strings_to_delete.txt`
do 
    sed "/$i/d" file.to_edit.txt > file.edited.txt &&
        mv file.edited.txt file.to_edit.txt
done

It deletes strings from file strings_to_delete.txt in file.to_edit.txt. File strings_to_delete.txt contains multiple lines with one string per line.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
diosko
  • 1
  • 1
  • 1
    What's new about this? That's exactly the same as existing answer (write to a temp file and if successful, move it over the original). – Toby Speight Dec 06 '18 at 12:56
  • There is no new info about tmp file, but there is info how to delete multiple strings using sed which I miss in previous conversation. Well, maybe not the right thread. – diosko Dec 06 '18 at 13:04
  • 1
    It looses the original permissions. – saulius2 Nov 15 '19 at 13:05