When working with text files, you’ll often need to find and replace strings of text in one or more files.
The sed is a stream editor. It is used to search, find and replace, insert and delete words and lines. You also can use the regular expressions. In this article we will show you how to find replace strings with sed
.
Find and Replace String with sed
By default most Linux distributions comes with GNU sed pre-installed. In macOS have the BSD version of the sed
.
Following the common syntax for searching and replacing text using sed
:
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
Here,
-i
– By default,sed
shows output to the standard output. Using this option yoused
will edit the files in place.s
– It’s substitute command and mostly used withsed
command./ / /
– The delimiter character. It can be any character but usually the slash (/
) character is used.SEARCH_REGEX
– Need to pass regular expression or normal string to search for.REPLACEMENT
– The string which want to replace with.g
– Indicates global replacement flag. Thesed
reads the files line by line and make changes for first occurrence of search keyword in a line. Using replacement flag it will replace for all occurrences.INPUTFILE
– File name for which you want to run the command.
It’s recommended to enclose the argument with quotes so shell meta-characters won’t expand.
Let’s see an example, there is a file named file1.txt
:
7002 Kunj kunj kunj
kunj /bin/bash Ubuntu kunjtns 789
If the g
flag is not used, it will replace the first instance of the search string in each line:
sed -i 's/kunj/tecnstuff/' file1.txt
7002 Kunj tecnstuff kunj
tecnstuff /bin/bash Ubuntu kunjtns 789
Using the global replacement flag sed
command will replace all occurrences of the search pattern:
sed -i 's/kunj/tecnstuff/g' file1.txt
7002 Kunj tecnstuff tecnstuff
tecnstuff /bin/bash Ubuntu tecnstufftns 789
In above output you can see that the kunj
inside the kuntns
string is also replaced. To prevent such behavior, you should use the word-boundary expression (\b
) at beginning and end of the search string.
sed -i 's/\bkunj\b/tecnstuff/g' file1.txt
7002 Kunj tecnstuff tecnstuff
tecnstuff /bin/bash Ubuntu kunjtns 789
Use I
flag, to make the pattern match case insensitive. You would use the command as following:
sed -i 's/kunj/tecnstuff/gI' file1.txt
7002 tecnstuff tecnstuff tecnstuff
tecnstuff /bin/bash Ubuntu tecnstufftns 789
If your search or replacement string contains delimiter character (/
) then you need to use the backslash (\
) to escape the slash. For instance, to replace /bin/bash
with /usr/bin/zsh
you would run:
sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file1.txt
You can make it easy and more readable by using the other delimiter character such as pipe or colon or any other:
sed -i 's|/bin/bash|/usr/bin/zsh|g' file1.txt
7002 Kunj kunj kunj
kunj /usr/bin/zsh Ubuntu kunjtns 789
Use of regular expression is a short and easy way to search and replacement. For example, to search 4 digit number and replace with the string replnumber
, you would run like below:
sed -i 's/\b[0-9]\{4\}\b/replnumber/g' file1.txt
replnumber Kunj kunj kunj
kunj /bin/bash Ubuntu kunjtns 789
Recursive Find and Replace
Sometimes you have requirement to check each files of directories to find searched string and replace in all files. You can do this using the find or grep
commands to recursively find files in directory.
For example, below command will recursively search for files in current working directory and pass the file name to sed
.
find . -type f -exec sed -i 's/kunj/tecnstuff/g' {} +
Use the -print0
option to prevent the issue of space in file names. It will convert the space to null character and pipe the output to sed
using xargs -0
:
If you want to exclude any directory you can do using -not -path
option. For instance, you replacing a string in your Laravel project directory and want to exclude all files starting with dot (.
), you would use:
find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/kunj/tecnstuff/g'
To search and replace text only on files with a specific extension, you will use:
find . -type f -name "*.css" -print0 | xargs -0 sed -i 's/kunj/tecnstuff/g'
Alternatively, you can use the grep command to recursively find all files containing the search pattern and then pipe the filenames to sed
:
grep -rlZ 'kunj' . | xargs -0 sed -i.bak 's/kunj/tecnstuff/g'
Conclusion
I hope you learned successfully how to search and replace text in files using sed.
If you have any questions or feedback, feel free to leave a comment.