Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive search and replace in text files on Mac and Linux

Tags:

linux

shell

macos

In the linux shell, the following command will recursively search and replace all instances of 'this' with 'that' (I don't have a Linux shell in front of me, but it should do).

find . -name "*.txt" -print | xargs sed -i 's/this/that/g'

What will a similar command on OSX look like?

like image 255
Jack Avatar asked Oct 07 '22 05:10

Jack


People also ask

How do I grep recursively on a Mac?

When the -R option is used, MacOS grep requires you to explicitly give it a directory to search; for example, specify . to recursively search the current directory: grep -R 'networks' .


1 Answers

OS X uses a mix of BSD and GNU tools, so best always check the documentation (although I had it that less didn't even conform to the OS X manpage):

https://web.archive.org/web/20170808213955/https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/sed.1.html

sed takes the argument after -i as the extension for backups. Provide an empty string (-i '') for no backups.

The following should do:

find . -type f -name '*.txt' -exec sed -i '' s/this/that/g {} +

The -type f is just good practice; sed will complain if you give it a directory or so.

-exec is preferred over xargs; you needn't bother with -print0 or anything.

The {} + at the end means that find will append all results as arguments to one instance of the called command, instead of re-running it for each result. (One exception is when the maximal number of command-line arguments allowed by the OS is breached; in that case find will run more than one instance.)

If you get an error like "invalid byte sequence," it might help to force the standard locale by adding LC_ALL=C at the start of the command, like so:

LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/g {} +

like image 85
TaylanKammer Avatar answered Oct 17 '22 06:10

TaylanKammer