Skip to content

Sed Basic Commands

This chapter describes several fundamental SED commands for text manipulation. We’ll use the following books.txt file for examples. Ensure your books.txt matches this content for consistent results:

File: `books.txt`
1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

The d command deletes lines from the pattern space. Deleted lines are not sent to the output stream, and the original file remains unchanged unless you use in-place editing (e.g., sed -i).

Syntax: `[address1[,address2]]d`

address1 and address2 specify the starting and ending lines or patterns for deletion. Both are optional. If no address is given, all lines are deleted.

Example: Delete all lines (no output).

[jerry]$ sed 'd' books.txt

This command produces no output because every line is read into the pattern space and then deleted before it can be printed.

Example: Delete the 4th line.

[jerry]$ sed '4d' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

Example: Delete lines from 2 through 4.

[jerry]$ sed '2,4d' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

Example: Delete lines containing the pattern “Paulo Coelho”.

[jerry]$ sed '/Paulo Coelho/d' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
6) A Game of Thrones, George R. R. Martin, 864

Example: Delete lines from the first match of “Storm” to the first match of “Fellowship”.

[jerry]$ sed '/Storm/,/Fellowship/d' books.txt

Output:

5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

You can also use special address characters like $ (last line), or GNU extensions like M~N (every Nth line starting at M).

The w file command writes the content of the pattern space to the specified file. This is useful for extracting parts of a file or creating backups. The file is created if it doesn’t exist and overwritten if it does.

Syntax: `[address1[,address2]]w file`

Note: There must be exactly one space between w and file.

Example: Create a backup copy of books.txt to books.bak.

[jerry]$ sed -n 'w books.bak' books.txt

Verify the copy:

[jerry]$ diff books.txt books.bak
[jerry]$ echo $?

Output (if files are identical):

0

Example: Write only even-numbered lines to junk.txt (uses GNU SED address extension M~N).

[jerry]$ sed -n '2~2 w junk.txt' books.txt
[jerry]$ cat junk.txt

Output (cat junk.txt):

2) The Two Towers, J. R. R. Tolkien, 352
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
6) A Game of Thrones, George R. R. Martin, 864

Example: Store books by different authors into separate files.

[jerry]$ sed -n -e '/Martin/w Martin.txt' -e '/Paulo/w Paulo.txt' -e '/Tolkien/w Tolkien.txt' books.txt

Check contents:

[jerry]$ cat Martin.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
6) A Game of Thrones, George R. R. Martin, 864
[jerry]$ cat Paulo.txt

Output:

3) The Alchemist, Paulo Coelho, 197
5) The Pilgrimage, Paulo Coelho, 288
[jerry]$ cat Tolkien.txt

Output:

2) The Two Towers, J. R. R. Tolkien, 352
4) The Fellowship of the Ring, J. R. R. Tolkien, 432

The a command appends text after the specified line or lines matching a pattern. The text to append follows the command, separated by a backslash if it spans multiple lines.

Syntax:
`[address]a\
text to append`
(For multi-line text, each subsequent line of text must also end with `\` except the last one.) Or for single line text:
`[address]a text to append` (GNU sed allows text on same line, POSIX requires newline after `a` unless it's the last command in script.) Best practice for portability is `[address]a\` then text on next line.

Example: Append a new book entry after line 4.

[jerry]$ sed '4a\
7) Adultery, Paulo Coelho, 234' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
7) Adultery, Paulo Coelho, 234
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

Example: Append text at the end of the file using $ address.

[jerry]$ sed '$a\
7) Adultery, Paulo Coelho, 234' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864
7) Adultery, Paulo Coelho, 234

The c command replaces entire existing line(s) with new text. If a range of lines is specified, all those lines are replaced as a group by the new text (which can be a single line or multiple lines).

Syntax:
`[address1[,address2]]c\
replacement text`
(Similar newline/backslash rules as `a` and `i` commands for `replacement text`.)

Example: Replace the third line.

[jerry]$ sed '3c\
3) Adultery, Paulo Coelho, 324' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) Adultery, Paulo Coelho, 324
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

The i command is similar to a, but it inserts text before the specified line or pattern match.

Syntax:
`[address]i\
text to insert`
(Similar newline/backslash rules as `a` command for `text to insert`.)

Example: Insert a new entry before the fourth line.

[jerry]$ sed '4i\
7) Adultery, Paulo Coelho, 324' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
7) Adultery, Paulo Coelho, 324
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

Example: Insert two lines before the last line ($).

[jerry]$ sed '$i\
7) Adultery, Paulo Coelho, 324\
8) Eleven Minutes, Paulo Coelho, 304' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288
7) Adultery, Paulo Coelho, 324
8) Eleven Minutes, Paulo Coelho, 304
6) A Game of Thrones, George R. R. Martin, 864

The y command transliterates characters. It replaces characters from a source-list with corresponding characters from a destination-list based on their position.

Syntax: `[address1[,address2]]y/source-list/destination-list/`

Important: source-list and destination-list must have the same number of characters. Regular expressions or character classes are not supported in these lists.

Example: Convert specific Arabic numbers (0, 1, 2, 5) to simple Roman-like characters (X, I, X, V respectively).

[jerry]$ echo "1 5 15 20" | sed 'y/0125/XIXV/'

Output:

I V IV XX

Explanation: ‘1’ becomes ‘I’, ‘5’ becomes ‘V’. So ‘15’ becomes ‘IV’. ‘2’ becomes ‘X’, ‘0’ becomes ‘X’. So ‘20’ becomes ‘XX’.

The l command displays the content of the pattern space in an unambiguous way, showing non-printable characters like tabs (\t) and end-of-line ($). An optional len argument (GNU extension) specifies a line wrap length.

Syntax:
`[address1[,address2]]l`
`[address1[,address2]]l [len]` (GNU extension)

Example: Create a file tabbed_books.txt with tabs instead of some spaces for demonstration.

[jerry]$ sed 's/ /\t/2g' books.txt > tabbed_books.txt

Now display hidden characters in tabbed_books.txt:

[jerry]$ sed -n 'l' tabbed_books.txt

Output (will vary based on where tabs were inserted, example shows \t for tabs and $ for EOL):

1) A Storm of\tSwords,\tGeorge R. R. Martin, 1216$
2) The Two\tTowers,\tJ. R. R. Tolkien, 352$
3) The Alchemist,\tPaulo\tCoelho, 197$
4) The Fellowship\tof\tthe Ring, J. R. R. Tolkien, 432$
5) The Pilgrimage,\tPaulo\tCoelho, 288$
6) A Game of\tThrones,\tGeorge R. R. Martin, 864$

Example: Wrap lines from books.txt after 25 characters (GNU extension).

[jerry]$ sed -n 'l 25' books.txt

Output:

1) A Storm of Swords,Geo\
rge R. R. Martin,1216$
2) The Two Towers,J. R. \
R. Tolkien,352$
3) The Alchemist,Paulo C\
oelho,197$
4) The Fellowship of the\
Ring,J. R. R. Tolkien,\
432$
5) The Pilgrimage,Paulo \
Coelho,288$
6) A Game of Thrones,Geo\
rge R. R. Martin,864$

A wrap limit of 0 (GNU extension) means never break the line unless there is an actual newline character.

The q command causes SED to stop processing and exit immediately. It can take an optional value (GNU extension) as an exit status.

Syntax:
`[address]q`
`[address]q [value]` (GNU extension)

Note: q only accepts a single address, not a range.

Example: Print the first 3 lines from the file and then quit.

[jerry]$ sed '3q' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197

Example: Quit when “The Alchemist” is found, with exit status 100 (GNU extension).

[jerry]$ sed '/The Alchemist/q 100' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197

Verify exit status:

[jerry]$ echo $?

Output:

100

The r file command reads the contents of file and appends them to the output after the current line (or after lines matching an address).

Syntax: `[address]r file`

Note: There must be exactly one space between r and file.

Example: Create junk.txt and insert its content after line 3 of books.txt.

[jerry]$ echo "This is junk text." > junk.txt
[jerry]$ sed '3r junk.txt' books.txt

Output:

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
3) The Alchemist, Paulo Coelho, 197
This is junk text.
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

GNU SED also accepts a range of addresses for r, inserting file contents after each matched line.

The e [command] command (a GNU extension) executes an external command. If command is omitted, the content of the pattern space is executed as a command.

Syntax: `[address1[,address2]]e [command]`

Example: Execute the date command before processing line 3.

[jerry]$ sed '3e date' books.txt

Output (date/time will be current):

1) A Storm of Swords, George R. R. Martin, 1216
2) The Two Towers, J. R. R. Tolkien, 352
[Current date and time will be shown here, e.g., Tue Jul 23 10:30:00 UTC 2024]
3) The Alchemist, Paulo Coelho, 197
4) The Fellowship of the Ring, J. R. R. Tolkien, 432
5) The Pilgrimage, Paulo Coelho, 288
6) A Game of Thrones, George R. R. Martin, 864

Example: If no command is given to e, SED executes the content of the pattern space. Create commands.txt:

[jerry]$ printf "date\ncal\nuname\n" > commands.txt
[jerry]$ cat commands.txt

Output (cat commands.txt):

date
cal
uname

Now execute these commands via SED:

[jerry]$ sed 'e' commands.txt

Output (will show current date, calendar, and system name like ‘Linux’):

[Output of 'date' command]
[Output of 'cal' command (current month's calendar)]
[Output of 'uname' command, e.g., Linux]

SED primarily operates line-by-line, but some commands handle multiple lines in the pattern space.

The N command appends the next input line to the pattern space, separated by an embedded newline (\n). This allows operations across line boundaries.

Syntax: `[address1[,address2]]N`

Example: Join pairs of lines from books_split.txt (title on one line, author on the next) into a single line. For this, we assume books_split.txt:

File: `books_split.txt`
A Storm of Swords
George R. R. Martin
The Two Towers
J. R. R. Tolkien
...
[jerry]$ sed 'N; s/\n/, /' books_split.txt

Output (first few lines):

A Storm of Swords, George R. R. Martin
The Two Towers, J. R. R. Tolkien
The Alchemist, Paulo Coelho
...

How it works: N reads line 1 (title), then appends line 2 (author), so pattern space is “Title\nAuthor”. s/\n/, / replaces \n with ”, ”. This repeats for subsequent pairs.

The P command prints the portion of a multi-line pattern space up to the first embedded newline (\n). Often used with N.

Syntax: `[address1[,address2]]P`

Example: Using books_split.txt, print only the titles (the first line of each pair).

[jerry]$ sed -n 'N;P' books_split.txt

Output (first few lines):

A Storm of Swords
The Two Towers
The Alchemist
...

Without N or other multi-line operations, P behaves like p (prints the entire pattern space).

The D command deletes the portion of a multi-line pattern space up to the first embedded newline. If the pattern space becomes empty, SED starts a new cycle. Otherwise, it restarts the script with the remaining content, without reading a new line. This is powerful for creating loops that process parts of a multi-line buffer.

Syntax: `[address1[,address2]]D`

The v [version] command (GNU extension) checks if the SED version is at least [version]. If not, it aborts. This is rarely used in scripts; sed --version is more common for manual checks.

Syntax: `[address1[,address2]]v version`

Example: Check current SED version.

[jerry]$ sed --version

Output (example):

sed (GNU sed) 4.8
...

Example: Abort if version is less than 4.9 (assuming current is 4.8).

[jerry]$ sed 'v 4.9' books.txt

Output (if version is less than 4.9):

sed: -e expression #1, char 5: expected newer version of sed

If the version check passes (e.g., sed 'v 4.8' books.txt), the command proceeds normally, printing lines from books.txt.