sed

sed: Powerful UNIX filter that parses and transforms text using a simple, compact programming language.

sed History:

Architecture

General Idea:

  1. Commands in a sed script are applied in order to each line.
  2. If a command changes the input, subsequent commands will be applied to the modified line in the pattern space, not the original input line.
  3. Results are sent to stdout.

Flow of Control:

  1. sed starts at the first line of the input file and runs it through the script file.
  2. sed reads the next line of the input and restarts from the beginning of the script file.
  3. etc…

When sed Copies a Line into Pattern Space…:

  1. If the address of the command matches the line in the pattern space, the command is applied to that line.
  2. If the command has no address, it is applied to every line as it enters pattern space.
  3. When all commands have been read, the line in pattern space is written to standard output and a new line is read into pattern space.

sed Scripts

Format: [address[, address]][!]command [arguments]

A script is a file of commands

Addressing

An address can be either a line number or a pattern, enclosed in slashes (/pattern/)

Most command accept two addresses:

  1. If one address is given, the command operates only on that line.
  2. If two comma-separated addresses are given, then the command operates on the range of lines between the first and second address, inclusively.

The ! operator can be used to negate an address.

Commands

Commands are written as single letters.

Examples: Using the delete command

$ sed 'd' < file.txt
$ sed '6d' < file.txt

Applying Multiple Commands to an Address ({})

Braces ({}) can be used to apply multiple commands to an address.

Format:

[/pattern/[,/pattern/]] {
  command1
  command2
  ...
}

Syntax Notes:

More on Commands

Tip: Commands can be separated from the [address] by spaces for readability.

Some Commands

d: delete

Format: [address1][,address2]d

Example: Using delete

$ sed '1,10d' < file.txt

p: print

Format: [address1][,address2]p

Example: Using print

$ sed -n '1,10 p' < file.txt

s: substitute

Format: [address(es)]s/pattern/replacement/[flags]

Note on substitution delimiters: The / delimiter can be escaped with \ if you want to use it literally in a pattern (e.g., sed 's/\/usr\/local\/bin/\/common\/bin/’ < file.txt),

Example: Using substitute

$ echo "I love Linux" | sed 's|Linux|GNU/Linux|g'
I love GNU/Linux

a: append

Format:

[address]a\
text

Note: append doesn’t accept address ranges.

Example: Using append

$ echo "Hello" | sed '/Hello/ a\World'
Hello
World

i: insert

Format:

[address]i\
text

Note: insert doesn’t accept address ranges.

Example: Using insert

$ echo "World" | sed '/World/ i\Hello'
Hello
World

c: change

Format:

[address(es)]c\
text

Example: Using change

$ echo "REPLACEME" | sed '/REPLACEME/ c\bingus'
bingus

y: transform

Format: [address[,address]] y/<string1>/<string2>/

Operates like tr. Does character-to-character translation.

Example: Using transform (y)

$ sed 'y/abc/xyz/'

q: quit

Format: [address]q

Note: quit takes at most one address.

Example: Using quit

sed '100 q' file.txt

Examples: Using p, d, and !

Examples: Using the delete command (more advanced)

$ sed '11,$ d' < file.txt
$ sed '1,/^$/ d' < file.txt
$ sed '/^$/' < file.txt
$ sed '/^$/,$d' < file.txt
$ sed '/^$/,10d' < file.txt
$ sed '/^ya*y/,/[0-9]$/d' < file.txt

Examples: Using the print command

$ sed 'p' < file.txt
$ sed -n 'p' < file.txt
$ sed '/^$' < file.txt
$ sed -n '1,10 p' < file.txt
$ sed -n '/^$/,$ p' < file.txt

Examples: Reversing restrictions with !

$ sed -n '/match/ p' < file.txt
$ sed -n '/match/ !p' < file.txt
$ sed -n '1,10 p’ < file.txt
$ sed -n '11,$ !p’ < file.txt
$ sed '1,10 !d’ < file.txt
$ sed '11,$ d' < file.txt

Examples: More on substitution

Examples: Using substitution

$ sed 's/one/ONE/g' < file.txt
$ sed 's/false/true/g' < file.txt

Example: Behavior of substitution (important!)

Suppose a file named file.txt with this content:

one two three, one two three four
three two one
one hundred

If you ran sed 's/one/ONE/' < file.txt, the output would be:

$ sed 's/one/ONE/' < file.txt
ONE two three, one two three four
three two ONE
ONE hundred

If you ran sed 's/one/ONE/2' < file.txt, the output would be:

$ sed 's/one/ONE/2' < file.txt
one two three, ONE two three four
three two one
one hundred

Examples: Using substitution (cont.)

$ sed ‘s/nice/bazinga/’ < file.txt
$ sed ‘s/Tom/Jerry/2’ < file.txt
$ sed -n ‘s/one/ONE/2 p’ < file.txt
$ sed '1,100 s/A/a/g’ < file.txt

Examples: More on Reversing Restrictions (!)

Examples: Using !

$ cat file.txt
The brown cow
The black cow
$ sed '/black/ !s/cow/horse/' < file.txt
The brown horse
The black cow
$ sed '1,5 !d' < file.txt

Example: Using append, insert, and change with {}

Example: Using append, insert, and change with curly braces ({}) $ cat file.txt That person looks pretty fishy. $ sed ‘/fishy/ { i
, Ponyo, Ponyo fishy in the sea a
who could you really be? c
Tiny little fishy, }’ < file.txt

Ponyo, Ponyo, Ponyo fishy in the sea Tiny little fishy, who could you really be?

Example: Using transform (y)

Example: Using transform (y)

$ echo "TESTING" | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'
testing