We use sed to work with text files like log files, configuration files, and other text files.
In this post, we are going to focus on the sed Linux command, which is used for text manipulation, which is an essential step in our bash scripting journey.
Linux system provides some tools for text processing; one of those tools is sed.
Understand sed Linux command
The sed command is a non-interactive text editor. Sed Linux command edits data based on the rules you provide; you can use it like this:
$ sed options file
You are not limited to use sed to manipulate files; you apply it to the STDIN directly like this:
$ echo "Welcome to LikeGeeks page" | sed 's/page/website/'
The s command replaces the first text with the second text pattern. In this case, we replaced the string “website” with the word “page”.
The above example was a simple example to demonstrate the tool. We can use the sed Linux command to manipulate files as well.
Let’s create a sample file :
$ sed 's/test/another test/' ./myfile
The results are printed to the screen instantaneously; you don’t have to wait for processing the file to the end.
If your file is massive enough, you will see the result before the processing is finished.
Sed Linux command doesn’t update your data. It only sends the changed text to STDOUT. The file is still untouched. If you need to overwrite the existing content, you can check our previous post, which was talking about redirections.
Using multiple sed Linux commands in the command line
To run multiple sed commands, you can use the -e option like this:
$ sed -e 's/This/That/; s/test/another test/' ./myfile
You must separate sed commands by a semicolon without any spaces.
Also, you can use a single quotation to separate commands like this:
$ sed -e ' > s/This/That/ > s/test/another test/' myfile
The same result, no big deal.
Reading commands from a file
You can save your sed commands in a file and use them by specifying the file using -f option.
$ cat mycommands s/This/That/ s/test/another test/
$ sed -f mycommands myfile
Substituting flags
Look at the following example carefully:
$ cat myfile
$ sed 's/test/another test/' myfile
The above result shows that we replaced the first occurrence in each line. To substitute all occurrences of a pattern, use one of the following substitution flags.
We can write the flags like this:
s/pattern/replacement/flags
There are four types of substitutions:
- g, replace all occurrences.
- A number, the occurrence number for the new text that you want to substitute.
- p, print the original content.
- w file: means write the results to a file.
You can limit your replacement by specifying the occurrence number that should be replaced like this:
$ sed 's/test/another test/2' myfile
As you can see, we replaced only the second occurrence on each line.
The g flag means global, which means a global replacement for all occurrences:
$ sed 's/test/another test/g' myfile
The p flag prints each line contains a pattern match, you can use the -n option to print the modified lines only.
$ cat myfile
$ sed -n 's/test/another test/p' myfile
The w flag saves the output to a specified file:
$ sed 's/test/another test/w output' myfile
We printed the output on the screen, but we saved the matching lines to the output file.
Replace characters
Suppose that you want to search for bash shell and replace it with csh shell in the /etc/passwd file using sed, well, you can do it easily:
$ sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd
Oh!! that looks terrible.
Luckily, there is another way to achieve that. You can use the exclamation mark (!) as string delimiter like this:
$ sed 's!/bin/bash!/bin/csh!' /etc/passwd
Now it’s easier to read.
Limiting sed
Sed command processes your entire file. However, you can limit the sed command to process specific lines; there are two ways:
- A range of lines.
- A pattern that matches a specific line.
You can type one number to limit it to a specific line:
$ sed '2s/test/another test/' myfile
We modified only line two.
What about using a range of lines:
$ sed '2,3s/test/another test/' myfile
Also, we can start from a line to the end of the file:
$ sed '2,$s/test/another test/' myfile
Or you can use a pattern like this:
$ sed '/likegeeks/s/bash/csh/' /etc/passwd
Awesome!!
You can use regular expressions to write this pattern to be more generic and useful.
Delete lines
To delete lines using sed, you can use the delete (d) flag is your friend.
The delete flag deletes the text from the stream, not the original file.
$ sed '2d' myfile
Here we delete the second line only from myfile.
What about deleting a range of lines?
$ sed '2,3d' myfile
Here we delete a range of lines, the second and the third.
Another type of ranges:
$ sed '3,$d' myfile
Here we delete from the third line to the end of the file.
All these examples never modify your original file.
$ sed '/test 1/d' myfile
Here we use a pattern to delete the line if matched on the first line.
If you need to delete a range of lines, you can use two text patterns like this:
$ sed '/second/,/fourth/d' myfile
We deleted from the second to the fourth line.
Insert and append text
You can insert or append text lines using the following flags:
- The (i) flag.
- The (a) flag.
$ echo "Another test" | sed 'i\First test '
We added the text before the specified line.
$ echo "Another test" | sed 'a\First test '
We added the text after the specified line.
Well, what about adding text in the middle?
Easy, look at the following example:
$ sed '2i\This is the inserted line.' myfile
And the appending works the same way, but look at the position of the appended text:
$ sed '2a\This is the appended line.' myfile
We used the same flags but with a location of insertion or appending.
Modifying lines
To modify a specific line, you can use the (c) flag like this:
$ sed '3c\This is a modified line.' myfile
You can use a regular expression pattern, and all lines match that pattern will be modified.
$ sed '/This is/c Line updated.' myfile
Transform characters
The transform flag (y) works on characters like this:
$ sed 'y/123/567/' myfile
We applied the transformation to all data, and we cannot limit it to a specific occurrence.
Print line numbers
You can print line number using the (=) sign like this:
$ sed '=' myfile
However, by using -n combined with the equal sign, the sed command displays the line number that contains matching.
$ sed -n '/test/=' myfile
Read data from a file
You can use the (r) flag to read data from a file.
You can define a line number or a text pattern for the text that you want to read.
$ cat newfile
$ sed '3r newfile' myfile
We inserted the content after the third line as expected.
And this is using a text pattern:
$ sed '/test/r newfile' myfile
Cool right?
Useful examples
Suppose that we have a file that contains text with a placeholder, and we have another file that contains the data that will fill the placeholder on the other file.
We will use the (r) and (d) flags to do the job.
The word DATA in that file is a placeholder for a real content that we will store in another file called data.
We will replace it with the actual content:
$ Sed '/DATA>/ { r newfile d}' myfile
Awesome!! as you can see, we filled the placeholder location with the data from the other file.
This is just a small intro about sed command. The sed Linux command is another world by itself.
The only limitation is your imagination.