How to Use sed Command to Find and Replace String in Files

Introduction

Before we begin talking about how to use sed commands to find and replace strings in the files. Let’s briefly understand - What is sed?

Sometimes when working with text files, there is a requirement for users to find and replace strings of text in one or more files. sed is a stream editor. It helps in the manipulation of files and input streams like pipelines. Using sed user can search, find and replace, insert, and delete words and lines. It supports both basic and extended regular expressions that allow users to match certain complex patterns.

In this tutorial, you will learn how to find and replace strings in the files with the sed command. We will also address some of the FAQs related to the sed command.

Step 1 - Find and Replace String with sed

1) sed has different versions with some functionality differences. macOS uses the BSD version, and most of the Linux distributions come with the pre-installed GNU. We will be using GNU in this article.

Following is the format for finding and replacing strings with sed command:

sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
  • -i - sed writes its output to standard output. This option indicates sed editing files in place. If an extension is supplied (ex -i.bak) then, a backup of the original file will be created.
  • s - It is the substitute command.
  • / / / -  The Delimiter character. It can be any character, but usually the slash (/) character is useful.
  • SEARCH_REGEX - A normal string, or regular expression, to search for.
  • REPLACEMENT - It is the replacement string.
  • g - The Global replacement flag. By default, sed reads file line by line. And only changes the first occurrence of SEARCH_REGEX but, if the replacement flag is given, all occurrences get replaced.
  • INPUTFILE - This is the name of the file on which you want to run the command.

2) It is a good practice to put quotes around the argument so that the shell meta-characters won't expand.

Now, let's check how to use sed command to search and replace text in files with some of its most commonly used options and flags.

123 Foo foo foo 
foo /bin/bash Ubuntu foobar 456

3) If you will omit the g flag, only the first instance of the search string will be replaced in each line:

sed -i 's/foo/linux/' file.txt
Output

123 Foo linux foo 
linux /bin/bash Ubuntu foobar 456

4) With global replacement flag sed replaces all occurrences of search pattern:

sed -i 's/foo/linux/g' file.txt
Output

123 Foo linux linux
linux /bin/bash Ubuntu linuxbar 456

5) As you will notice, in the previous example, the substring foo inside foobar string also gets replaced. If it is not the required behavior, use word-boundary expression (\b) at both ends of the search string. It will ensure that the partial words are not matched:

sed -i 's/\bfoo\b/linux/g' file.txt
Output

123 Foo linux linux
linux /bin/bash Ubuntu foobar 456

6) To make pattern match case-insensitive. You will use the I flag. Like below, you can use both g and I flags:

sed -i 's/foo/linux/gI' file.txt
Output

123 linux linux linux 
linux /bin/bash Ubuntu linuxbar 456

7) If you want to find and replace a string containing delimiter character (/) then, you will need to use the backslash (\). It will escape the slash. Like to replace /bin/bash with /usr/bin/zsh you will use the following:

sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt

8) The easier and much readable option is to use another delimiter character. Many people use vertical bar (|) or colon (:). But you can use any other character as well:

sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt
Output

123 Foo foo foo 
foo /usr/bin/zsh Ubuntu foobar 456

9) You can also use regular expressions, say you want to search for all 3-digit numbers and replace them with the string number you can use the following command:

sed -i 's/\b[0-9]\{3\}\b/number/g' file.txt
Output

number Foo foo foo 
foo /bin/bash demo foobar number

10) Other useful feature of sed is using the ampersand character &. It corresponds to the matched pattern. The character is useful multiple times. If you want to add curly braces {} around each 3-digit number. Then you will need to type:

sed -i 's/\b[0-9]\{3\}\b/{&}/g' file.txt
Output

{123} Foo foo foo 
foo /bin/bash demo foobar {456}

11) It is always recommended to make a backup of the file on which you are using sed command. For example, if you are working on file.txt, you can save the original file as file.txt.bak using the following command:

sed -i.bak 's/foo/linux/g' file.txt

12) If you want to make sure that backup is created, list the files with ls command:

ls
Output

file.txt file.txt.bak

Step 2 - Recursive Find and Replace

1) Sometimes you will want to recursively search directories for a file that contains a string and replace that particular string in all the files. This is done by using commands like find or grep. It is to recursively find files in the directory and piping the file names to sed.

The below command will recursively search for files in the current working directory and pass the file names to sed:

find . -type f -exec sed -i 's/foo/bar/g' {} +

2) Now, to avoid issues with files having space in their names, you can use the -print0 option. It tells find to print the file name along with a null character and pipe the output to sed using xargs -0:

find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'

3) If you want to skip a directory, you should use -not -path option. For example, if you want to replace a string in your local git repository to exclude all the files starting with dot (.), use the following command:

find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g'

4) Now, if you want to search and replace text only on files with specific extension, you will use the following command:

find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'

5) Other option is to use grep command. It will recursively find all files having the search pattern. Further, to pipe the filenames to sed:

grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'

FAQs to Use sed Command to Find and Replace String in Files

Can sed search and replace strings in multiple files simultaneously?

Yes, sed can search and replace strings in multiple files by specifying the filenames as arguments after the sed command.

Can sed replace multiple occurrences of a string in a file?

Yes, by using the 'g' (global) flag at the end of the sed command, it will replace all occurrences of the string in a file.

Can sed search and replace strings in multiple files simultaneously? 

Yes, sed can search and replace strings in multiple files by specifying the filenames as arguments after the sed command.

How do I make sed replace a string in-place, directly modifying the original file? 

To make sed replace a string in-place, you can use the -i option followed by an optional backup file extension. For example, sed -i.bak 's/oldString/newString/g' input_file.

Can sed perform case-insensitive find and replace operations? 

Yes, you can use the I flag for case-insensitive find and replace. For example, sed 's/oldString/newString/gI' input_file will replace 'oldString' regardless of its case.

How can I remove lines containing a specific string using sed? 

To remove lines containing a specific string using sed, you can use the command: sed '/string/d' input_file.

Is it possible to replace only the first occurrence of a string using sed? 

Yes, by default, sed replaces all occurrences of a string. To limit it to only the first occurrence, you can use the 1 flag after the 's' command. For example, sed '0,/^oldString/s//newString/' input_file.

Conclusion

We hope this detailed guide helped you in understanding how to use sed to find and replace string in the files.

If you have any queries, please leave them in the comment below. We'll be happy to answer them.