23. Multiple Sed Commands in Command Line
As we showed in Chapter 1, there are several methods to execute multiple sed commands from the command line.
1. Use multiple -e option in the command line
Use multiple sed commands using -e sed command line option as shown below:
sed -e 'command1' -e 'command2' -e 'command3'
Search for root, or nobody, or mail in the /etc/passwd file:
sed -n -e '/^root/ p' -e '/^nobody/ p' -e '/^mail/ p' /etc/passwd
The above command should be executed in a single line as shown below.
sed -n -e '/^root/ p' -e '/^nobody/ p' -e '/^mail/ p' /etc/passwd
2. Break-up several sed commands using \
When you have a very long command, such as when executing several sed commands in the command line using -e, you can break it up using \.
sed -n -e '/^root/ p' \
-e '/^nobody/ p' \
-e '/^mail/ p' \
/etc/passwd
3. Group multiple commands using { }
When you have a lot of sed commands to be executed, you can group them together using { } as shown below.
sed -n '{
/^root/ p
/^nobody/ p
/^mail/ p
}' /etc/passwd
24. Sed Script Files
If you want to reuse a set of sed commands, create a sed script file with all the sed commands and execute it using -f command line option as shown below.
First, create a file that contains all the sed commands as shown below. You already know what these individual sed commands do, as we explained it in the previous sections.
$ vi mycommands.sed
s/\([^,]*\),\([^,]*\),\(.*\).*/\2,\1,\3/g
s/^.*/<&>/
s/Developer/IT Manager/
s/Manager/Director/
Next, execute this sed command file on the input file.
$ sed -f mycommands.sed employee.txt
25. Sed Comments
Sed comments start with a #. We all understand that sed uses very cryptic language. The sed commands that you write today might look unfamiliar if you view them after a long time. So, it is recommended to document what you mean inside the sed script file using sed comments, as shown below.
$ vi mycommands.sed
# Swap field 1 (employee id) with field 2 (employee name)
s/\([^,]*\),\([^,]*\),\(.*\).*/\2,\1,\3/g
# Enclose the whole line within < and >
s/^.*/<&>/
# Replace Developer with IT Manager
s/Developer/IT Manager/
# Replace Manager with Director
s/Manager/Director/
Note: If the 1st 2 characters of the 1st line in the *.sed script are #n, sed will automatically use the -n (don't print the pattern buffer) option.
26. Sed as an Interpreter
Just as you write shell scripts and execute them from the command line just by calling the file name, you can set up sed scripts for execution from the command line, i.e. Sed can be involved as an interpreter. To do this, add "#!/bin/sed -f" as the 1st line to your sed- script.sh file as shown below.
$ vi myscript.sed
#!/bin/sed -f
# Swap field 1 (employee id) with field 2 (employee name)
s/\([^,]*\),\([^,]*\),\(.*\).*/\2,\1,\3/g
# Enclose the whole line within < and >
s/^.*/<&>/
# Replace Developer with IT Manager
s/Developer/IT Manager/
# Replace Manager with Director
s/Manager/Director/
Now, execute the sed script directly by invoking it from the command line.
chmod u+x myscript.sed
./myscript.sed employee.txt
You can also specify -n in the 1st line of the sed script to suppress output.
$ vi testscript.sed
#!/bin/sed -nf
/root/ p
/nobody/ p
Now, execute the above test script as shown below.
chmod u+x testscript.sed
./testscript.sed /etc/passwd
Just for testing purposes, remove the -n from the 1st line of testscript.sed and execute it again to see how it works.
Important note: you must use -nf (and not -fn). If you specify -fn, you'll get the following error message when you execute the sed script.
$ ./testscript.sed /etc/passwd
/bin/sed: couldn't open file n: No such file or directory
27. Modifying the Input File Directly
As you know already, sed doesn't modify the input files by default. Sed writes the output to standard output. When you want to store that in a file, you redirect it to a file (or use the w command.
Before we continue with this example, take a backup of employee.txt.
cp employee.txt employee.txt.orig
To make a modification directly on the input-file, you typically redirect the output to a temporary file, and then rename the temporary file to a new file.
sed 's/John/Johnny/' employee.txt > new-employee.txt
mv new-employee.txt employee.txt
Instead, you can use the sed command line option -i, which lets sed directly modify the input file.
Replace John with Johnny in the original employee.txt file itself:
$ sed -i 's/John/Johnny/' employee.txt
$ cat employee.txt
101,Johnny Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
Again, please pay attention that -i modifies the input-file. Probably you will want to do this sometimes, but be very careful. One thing you can do to protect yourself is to add a file extension whenever you use -i. Sed will make a backup of the original file before writing the new content.
Replace John with Johnny in the original employee.txt file but save a backup copy:
$ sed -ibak 's/John/Johnny/' employee.txt
This takes the backup of the original file as shown below.
$ cat employee.txtbak
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
The original input file was modified by the above sed command.
$ cat employee.txt
101,Johnny Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Sales Manager
Instead of -i, you can also use the longer form, --in-place. Both of the following commands are the same.
sed -ibak 's/John/Johnny/' employee.txt
sed --in-place=bak 's/John/Johnny/' employee.txt
Finally, restore the original employee.txt file, as we need that for the rest of our examples:
cp employee.txt.orig employee.txt