If you've ever needed to replace a specific word or path across hundreds of files, you’re not alone. I’ve been there - manually opening file after file, making the same change over and over. It’s slow, boring, and prone to mistakes. That’s when I discovered how powerful bulk text replacement in Bash can be.
In this post, I’ll explain how to search and replace text across many files at once using Bash in Linux, with a practical example.
Note: This article is specifically written for BASH, but I assume that the instructions are same for other shells.
Table of Contents
Why Use Bash for Bulk Text Replacement?
Bash is already on most Linux and macOS systems (and can be added to Windows). It comes with powerful command-line tools like grep
, xargs
, and sed
. When combined, these tools can search through thousands of files and edit them in seconds, without needing to install anything new.
If you're a developer, system administrator, or just someone managing a bunch of text files, Bash can save you hours of manual work.
Find and Replace Text Across Files
Here is a Bash command that finds and replaces text in multiple files, at once:
grep -RiIl 'search' | xargs sed -i 's/search/replace/g'
Command Explanation:
grep -RiIl 'search'
-R
: Searches files recursively in subdirectories.-i
: Ignores case (case-insensitive search).-I
: Ignores binary files.-l
: Lists only filenames that contain the search term.
| xargs sed -i 's/search/replace/g'
xargs
: Passes filenames tosed
.sed -i
: Edits files in place.'s/search/replace/g'
: Replaces all occurrences of "search" with "replace".
Example: Updating Log files Path
Let’s say I have a directory called ~/example_project/
that contains some configuration and script files. Inside several files, I’ve hardcoded a path like /logs/
, but I’ve since renamed the folder to /log/
.
Here’s how I’d fix it across multiple files.
Step 1: Create a Test Environment
First, let’s make some test files to work with:
mkdir -p ~/example_project cd ~/example_project echo "Log files are stored in /logs/app1/" > config1.txt echo "Log directory: /logs/app2/" > config2.txt echo "No logging here" > notes.txt
Now check the contents:
cat config1.txt
You will see the following output:
Log files are stored in /logs/app1/
Step 1: Find All Files Containing /logs/
We’ll use grep
to search for that string:
grep -RiIl '/logs/' .
Please mind the .
(dot). It represents the current directory i.e. ~/example_project
in this case.
You will get the following output:
./config1.txt ./config2.txt
This confirms that only two files need changes.
Step 3: Replace /logs/
with /log/
in All Matching Files
Now we do the bulk replacement:
grep -RiIl '/logs/' . | xargs sed -i.bak 's|/logs/|/log/|g'
Let’s break it down:
grep -RIl '/logs/' .
: Find files that contain/logs/
in the current directory. Here.
represents the current directoryxargs
: Feeds those files intosed
.sed -i.bak
: Edits files in-place and saves backups as.bak
files.'s|/logs/|/log/|g'
: Replaces all instances of/logs/
with/log/
.s
is for "substitute" andg
means "global" i.e. change all instances on a line.
Note: You can also explicitly mention the directory path like below:
grep -RIl '/logs/' ~/example_project | xargs sed -i.bak 's|/logs/|/log/|g'
Step 4: Verify the Change
Check the edited file:
cat config1.txt
Sample Output:
Log files are stored in /log/app1/
Please note that text has changed from /logs/app1/
to /log/app1/
.
And let us check the backup file:
cat config1.txt.bak
Sample Output:
Log files are stored in /logs/app1/
Did you notice? The backup file (i.e. original file) still has the old text /logs/app1
.
Perfect! Now you’ve safely updated the text and preserved a copy of the original.
Roll Back If Needed
If something went wrong, you can restore the originals:
mv config1.txt.bak config1.txt mv config2.txt.bak config2.txt
Isn’t Renaming the Directory Easier?
You might be wondering why do't we just rename the directory. Good point — yes, renaming a directory is often much simpler than doing a bulk text replacement.
For example, you might think:
mv logs log
Done, right?
But here’s the key difference:
Renaming a folder only changes its name in the filesystem. It doesn’t update any file that refers to that path.
If you have hardcoded references like /logs/
inside your scripts, configs, or documentation, they’ll still point to the old name and your system may break or behave unexpectedly. For example, if a config file contains ~/example_project/logs/error.log
, that string still says /logs/
, even though the directory is now /log/
.
That’s where bulk text replacement helps. It updates all those references so everything stays consistent after the rename.
It rewrites hardcoded paths (like /logs/access.log
) inside source files, scripts, config files, etc. It is useful when absolute paths are written into code or data files.
Think of it this way:
mv logs log
→ changes the actual folder.grep + sed
→ updates references to that folder inside files.
They’re complementary tools, not interchangeable ones.
Conclusion
Bulk text replacement in Bash is one of those superpowers you don’t realize you need — until you do. Once you learn it, you’ll use it all the time to:
- Fix hardcoded paths.
- Update config values.
- Clean up typos in big projects.
- Refactor legacy codebases.
It’s fast, scriptable, and works anywhere Bash is available. Just remember to test first and make backups if you're not sure.
Have you used Bash to edit a bunch of files at once? Got a trick I didn’t cover? Leave a comment and share your approach.
Special Thanks to our Reader "EarBiteR" for sharing this useful tip.
Related Read: