I want to replace for example all instances of “123” with “321” contained within all .txt files in a folder (recursively).
I thought of doing this
sed -i 's/123/321/g' | find . -name \*.txt
but before possibly screwing all my files I would like to ask if it will work.
You have the
sedand thefindback to front. With GNUsedand the-ioption, you could use:The
findfinds files with extension.txtand runs thesed -icommand on groups of them (that’s the+at the end; it’s standard in POSIX 2008, but not all versions offindnecessarily support it). In this example substitution, there’s no danger of misinterpretation of thes/123/321/gcommand so I’ve not enclosed it in quotes. However, for simplicity and general safety, it is probably better to enclose thesedscript in single quotes whenever possible.You could also use
xargs(and again using GNU extensions-print0tofindand-0and-rtoxargs):The
-rmeans ‘do not run if there are no arguments’ (so thefinddoesn’t find anything). The-print0and-0work in tandem, generating file names ending with the C null byte'\0'instead of a newline, and avoiding misinterpretation of file names containing newlines, blanks and so on.Note that before running the script on the real data, you can and should test it. Make a dummy directory (I usually call it
junk), copy some sample files into the junk directory, change directory into the junk directory, and test your script on those files. Since they’re copies, there’s no harm done if something goes wrong. And you can simply remove everything in the directory afterwards:rm -fr junkshould never cause you anguish.