Chapter 4. Sed Execution

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