If you need to change a specific string of text across dozens or hundreds of files in Linux, doing it manually with a text editor is incredibly tedious and prone to human error. Whether you are updating a domain name in configuration files, fixing a typo in source code, or changing environment variables, you need a way to automate the process.
The sed (Stream Editor) command is one of the most powerful text-processing tools built into Linux. While it is often used to modify a single file, you can easily combine it with the find command to search and replace text across an entire directory structure simultaneously.
In this guide, we will show you how to safely perform bulk text replacements using sed directly from the terminal.
The Basic sed Search and Replace Command
Before modifying multiple files, it is vital to understand how sed replaces text in a single file. The basic syntax is:
sed -i 's/old_text/new_text/g' filename.txt
Breaking down the syntax:
- -i (in-place): This flag tells sed to save the changes directly back into the original file. Without it, sed just prints the modified text to the screen without changing the file.
- s/ (substitute): The ‘s’ indicates that you are performing a substitution operation. The forward slash separates the different parts of the command.
- old_text: The exact string you want to find.
- new_text: The string you want to replace it with.
- /g (global): This flag tells sed to replace every instance of the word on a line. Without it, sed will only replace the first instance it finds on each line.
How to Replace Text in Multiple Files
To run this substitution on multiple files, we combine sed with the find command. This allows us to target specific file types within a directory and its subdirectories.
The command structure looks like this:
find /path/to/directory -type f -name "*.txt" -exec sed -i 's/old_text/new_text/g' {} +
Breaking down the find syntax:
- find /path/to/directory: Tells Linux where to start searching. Use
.(a single period) to search the current directory. - -type f: Ensures the command only looks at files, not directories.
- -name "*.txt": Filters the search to only include files ending in .txt. (You can change this to
*.html,*.conf, or remove it entirely to target all files). - -exec … {} +: This tells find to take every file it locates and pass it into the
sedcommand. The{}represents the filenames.
A Real-World Example
Imagine you have a directory full of HTML files, and you need to update the copyright year in the footer from “2023” to “2024”.
- Open your terminal and navigate to the root directory of your HTML files.
- Run the following command:
find . -type f -name "*.html" -exec sed -i 's/Copyright 2023/Copyright 2024/g' {} +
Linux will instantly search every HTML file in that folder (and any folders inside it), locate the exact phrase “Copyright 2023”, and replace it with “Copyright 2024”.
Important Safety Tips Before Running Sed
Because sed -i modifies files immediately without asking for confirmation, a single typo can permanently ruin your files. Always follow these safety rules:
1. Create Backups Automatically
You can tell sed to create a backup of every file before it modifies it by providing a backup extension to the -i flag. For example, using -i.bak will create a copy of the original file ending in .bak.
find . -type f -name "*.txt" -exec sed -i.bak 's/old/new/g' {} +
2. Test Without the -i Flag First
If you are using a complex substitution or regular expressions, remove the -i flag first. This forces sed to print the results to your screen (stdout) instead of modifying the files, allowing you to visually verify that the replacement is working exactly as intended.
Once you are confident the output is correct, press the up arrow to recall the command, add the -i flag back in, and execute it for real.