Having built a little foundation, we can now start to look at some of the operations of sed
. The commands will be supplied with most Linux systems and are core commands.
We will dive directly into some simple examples:
$ sed 'p' /etc/passwd
The p
operator will print the matched pattern. In this case, we have not specified a pattern so we will match everything. Printing the matched lines without suppressing STDOUT
will duplicate lines. The result of this operation is to print all the lines in the passwd
file twice. To suppress STDOUT
, we use the -n
option:
$ sed -n 'p' /etc/passwd
Brilliant!!We have just reinvented the cat
command. We can now specifically work with just a range of lines:
$ sed -n '1,3 p ' /etc/passwd
Now we have reinvented the head
command, but we can also specify the range in an RE to recreate the grep
command:
$ sed -n '/^root/ p' /etc/passwd
We can see this demonstrated in the following screenshot:
We have seen the p
command for printing the pattern space. We will now look at the substitute command or s
. With this command, we can replace one string with another. Again by default, we send the output to the STDOUT
and do not edit the file.
To replace the default shell of the user pi
, we can use the following command:
sed -n ' /^pi/ s/bash/sh/p ' /etc/passwd
We continue the earlier instance using the p
command to print the matched pattern and use the -n
option to suppress STDOUT
. We search for lines beginning with pi
. This represents the username. We then issue the s
command to substitute text in those matched lines. This takes two arguments, the first is the text to search for and the second represents the text used to replace the original. In this case, we look for bash
and replace it with sh
. This is simple and does work but it may not be reliable in the long term. We can see the output in the following screenshot:
We must emphasize that currently we are not editing the file and just displaying it to the screen. The original passwd
file remains untouched and we can run this as a standard user. I mentioned in the previous example that the search may be less than reliable as the string we are searching for is bash
. This is very short and perhaps it can be included elsewhere on a matched line. Potentially, someone's last name may be "Tabash", which includes the string bash
. We can extend the search to look for /bin/bash
and replace it with /bin/sh
. However, this introduces another problem, which is, the default delimiter is the forward slash so we will have to escape each forward slash we use in the search and replace string, which is:
sed -n ' /^pi/ s//bin/bash//usr/bin/sh/p ' /etc/passwd
This is an option but it is not a tidy option. A better solution is to know that the first delimiter we use defines the delimiters. In other words, you can use any character as a delimiter. Using the @
symbol may be a good idea in this scenario, as it does not appear in either the search or the replace string:
sed -n ' /^pi/ s@/bin/bash@/usr/bin/sh@p ' /etc/passwd
We now have a more reliable search and a readable command line to work with, which is always a good thing. We replace just the first occurrence on each line of /bin/bash
with /bin/sh
. If we need to replace more than the first occurrence, we add the g
command for global at the end:
sed -n ' /^pi/ s@bash@sh@pg ' /etc/passwd
If we want to edit the file we can use the -i
option. We will need permissions to work with the file but we can make a copy of the file to work with, so we don't harm any system file or require additional access.
We can copy the passwd
file locally:
$ cp /etc/passwd "$HOME" $ cd
We finish with the cd
command to ensure that we are working in the home directory and the local passwd
file.
The -i
option is used to run an in-place update. We will not need the -n
option or the p
command when editing the file. As such, the command is as simple as the following example:
$ sed -i ' /^pi/ s@/bin/bash@/bin/sh/ ' $HOME/passwd
There will be no output to the command but the file will now reflect the change. The following screenshot shows the command usage:
We should make a backup before we make the change by appending a string directly after the -i
option and without any spaces. This is shown in the following example:
$ sed -i.bak ' /^pi/ s@/bin/bash@/bin/sh/ ' $HOME/passwd
If we want to see this, we can reverse the search and replace strings:
$ sed -i.bak ' /^pi/ s@/bin/sh@/bin/bash/ ' $HOME/passwd
This will set the local passwd
file to be the same as it was before and we will have a passwd.bak
with the previous set of changes. This keeps us safe with a rollback option if we need it.
3.142.136.226