4 ms·
Reminds me of how easy it is to destroy a file with sed: sed 's/a/b/' test.txt > test.txt After that command the file is empty no matter what was in there b
by JepZ 9y ago
Reminds me of how easy it is to destroy a file with sed:
sed 's/a/b/' test.txt > test.txt
After that command the file is empty no matter what was in there before. Instead you have to use the -i flag like:
sed 's/a/b/' -i test.txt
And different operating systems seem to behave differently:
https://stackoverflow.com/questions/5171901/sed-command-find-and-replace-in-file-and-overwrite-file-doesnt-work-it-empties https://stackoverflow.com/questions/5171901/sed-command-find...
- goialoq 9y agonoclobber https://en.wikipedia.org/wiki/Clobbering https://en.wikipedia.org/wiki/Clobbering
- jle17 9y agoMaybe this is just me but when I enable that king of options I end up getting the automatism of bypassing them (like typing rm -f everytime if rm has been aliased to rm -i). I prefer having a way of reverting changes rather than something that gets in the way.
- Ao7bei3s 9y agosed -i also has the less obvious advantage that it is atomic. (It writes to a temporary file, and then atomically renames it to the final location. Whereas if sed expr src > dst is killed, dst may be corrupt. You'd need to handle temporary file management yourself if your script needs to be reliable.)
- contingencies 9y agoMy memory is to sed -i -e 's/pattern/replacement/' file, the addition of -e was perhaps subconsciously to help protect against this eventuality by mentally segregating my standard pipeline invocation which takes neither argument. Anyway sed is so fast you should definitely check the output before overwriting stuff. Same goes for anything on the command line. Get ZFS. Do snapshots.
- ramshorns 9y ago> you should definitely check the output before overwriting stuff That wouldn't really help in the case of redirecting sed to the same file. $ echo "a" > test.txt $ sed s/a/b/ test.txt b $ sed s/a/b/ test.txt > test.txt $ cat test.txt $
- contingencies 9y agoIndeed. Use >> in preference to > at all times ;)
- icebraining 9y agoAs a sidenote, if you're using a command that doesn't have -i, or a chain of commands where the file is read at the start and written at the end, you can use sponge(1) from moreutils to achieve that without temporary files: sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd https://joeyh.name/code/moreutils/ https://joeyh.name/code/moreutils/
- userbinator 9y agoThat's not due to sed, but the shell; the > operator always opens the output file for writing in create-if-not-exists, truncate-existing mode, and that redirection processing happens before any commands are executed.
- kps 9y agoksh has ‘>;’, but bash hasn't picked that up. This better fits the compositional Unix philosophy than sprinkling a subset of individual commands with the functionality.
- Sean1708 9y agoDoes >; have an ascii name? Symbol Hound isn't bringing up any useful results.
- kps 9y agoI don't know what you mean by ASCII name. It's two characters, ‘>’ (ASCII 03/14) followed by ‘;’ (03/11). I guess the ‘;’ is mnemonic for the sequential nature of the operation, i.e. renaming the temporary file after the command completes, as well as forming a combination that is a syntax error in sh.
- Sean1708 9y agoWhen I said ASCII I actually meant alphanumerical, sorry. Basically I couldn't find any information about it on search engines so I was wandering if a had a name that I could use to google it.
- kps 9y agoI think the man page¹ is the only readily available documentation. >;word Write output to a temporary file. If the command completes successfully rename it to word, otherwise, delete the temporary file. >;word cannot be used with the exec(2) built-in. ¹ e.g. https://www.freebsd.org/cgi/man.cgi?query=ksh93&apropos=0&sektion=0&manpath=FreeBSD+11.1-RELEASE+and+Ports&arch=default&format=html https://www.freebsd.org/cgi/man.cgi?query=ksh93&apropos=0&se...