Logo

How to replace a string in multiple files in linux command line?

You can replace a string across multiple files using sed in combination with find or grep. Below are a few common approaches:

1. Using sed with find

If you already know which files to include (e.g., all .txt files), you can use find and then apply sed to each file:

find /path/to/dir -type f -name "*.txt" -exec sed -i 's/old_string/new_string/g' {} +
  • -type f -name "*.txt": Finds all regular files ending with .txt.
  • -exec ... {} +: Executes the sed -i command on all matching files in batches.
  • sed -i 's/old_string/new_string/g' file: Edits files in place (-i), replacing every occurrence of old_string with new_string.
  • g (global) ensures all instances of old_string in each line are replaced.

Using Case-Insensitive Matching

If you need a case-insensitive match:

find /path/to/dir -type f -name "*.txt" -exec sed -i 's/old_string/new_string/gi' {} +

The i after the second slash makes it case-insensitive.

2. Using grep and xargs

If you’d like to see which files contain the target string first, then pipe them to sed, you can use grep -l plus xargs:

grep -rl "old_string" /path/to/dir | xargs sed -i 's/old_string/new_string/g'
  1. grep -rl "old_string" /path/to/dir: Recursively lists files (-r) that contain old_string (-l shows only filenames).
  2. | xargs sed -i 's/old_string/new_string/g': Feeds the list of files to sed for in-place substitution.

Handling Special Filenames

If filenames contain spaces or special characters, use -0 (null-terminated strings):

grep -rlZ "old_string" /path/to/dir | xargs -0 sed -i 's/old_string/new_string/g'
  • -Z (grep) and -0 (xargs) ensure proper handling of filenames with whitespace.

3. Dry-Run Approach

To confirm the changes before overwriting files, skip -i (in-place) first and just output results to the terminal:

find /path/to/dir -type f -name "*.txt" -exec sed 's/old_string/new_string/g' {} +

Once satisfied with what you see, add -i to commit the changes:

find /path/to/dir -type f -name "*.txt" -exec sed -i 's/old_string/new_string/g' {} +

4. Edge Cases and Considerations

  • Binary or Non-Text Files: Make sure you’re only processing text files. Otherwise, binary data can be corrupted.
  • Escaping Special Characters: If your old_string or new_string contain characters that are special to sed (like / or &), you’ll need to escape them or use alternative delimiters, for example:
    sed -i 's|old/path|new/path|g' file
  • Backup Files: If you want a backup of the original before editing, you can specify a suffix for -i, e.g. sed -i.bak 's/old/new/g' file.
  • Performance: For large directories, using -exec ... {} + or piping to xargs in batches is more efficient than executing sed once per file.

Further Learning

To improve your overall efficiency with scripting and problem-solving, here are two recommended courses from DesignGurus.io:

  1. Grokking Data Structures & Algorithms for Coding Interviews
    Helps you craft more optimized solutions for tasks like searching/replacing across large sets of files.

  2. Grokking the Coding Interview: Patterns for Coding Questions
    Teaches you the essential patterns that top companies expect you to know, boosting your scripting and coding efficiency across a variety of challenges.

By combining powerful command-line tools (like sed and grep) with strong algorithmic thinking, you’ll handle file-processing tasks quickly and confidently.

CONTRIBUTOR
TechGrind