Wednesday, 14 August 2019

bash - How can I do a recursive find and replace from the command line?


Using a shell like bash or zshell, how can I do a recursive 'find and replace'? In other words, I want to replace every occurrence of 'foo' with 'bar' in all files in this directory and its subdirectories.



Answer



This command will do it (tested on both Mac OS X Lion and Kubuntu Linux).


# Recursively find and replace in files
find . -type f -name "*.txt" -print0 | xargs -0 sed -i '' -e 's/foo/bar/g'

Here's how it works:



  1. find . -type f -name '*.txt' finds, in the current directory (.) and below, all regular files (-type f) whose names end in .txt

  2. | passes the output of that command (a list of filenames) to the next command

  3. xargs gathers up those filenames and hands them one by one to sed

  4. sed -i '' -e 's/foo/bar/g' means "edit the file in place, without a backup, and make the following substitution (s/foo/bar) multiple times per line (/g)" (see man sed)


Note that the 'without a backup' part in line 4 is OK for me, because the files I'm changing are under version control anyway, so I can easily undo if there was a mistake.


To avoid having to remember this, I use an interactive bash script, as follows:


#!/bin/bash
# find_and_replace.sh

echo "Find and replace in current directory!"
echo "File pattern to look for? (eg '*.txt')"
read filepattern
echo "Existing string?"
read existing
echo "Replacement string?"
read replacement
echo "Replacing all occurences of $existing with $replacement in files matching $filepattern"

find . -type f -name $filepattern -print0 | xargs -0 sed -i '' -e "s/$existing/$replacement/g"

No comments:

Post a Comment

How can I VLOOKUP in multiple Excel documents?

I am trying to VLOOKUP reference data with around 400 seperate Excel files. Is it possible to do this in a quick way rather than doing it m...