Translation(s): none

(!) ?Discussion


This page is a quick tutorial about sed.

Pre-requisites:

The "s" (search and rplace) command

A simple search and replace

Let's assume we have a test file named test1.txt containing

Let's instruct sed to edit the file test1.txt, and run the command s (i.e search and replace) to search for "apples" and replace all of them with "oranges", then prints the result:

sed -e "s/apples/oranges/g" test1.txt

Expression delimiter

So we run:

sed -e "s,e,XXX," test1.txt

Only the first, lower case, "e" of each line were replaced.

Case sensitivity

if we pass the option i, the matching will become case-insensitive :

sed -e "s,e,XXX,gi" test1.txt

Will replace each and every instance of e or E in the file :

Regular Expression

The great thing about sed is that it works with regular expressions :

sed -e "s,[eE],XXX,g" test1.txt

Will replace each and every instance of e or E in the file :

It is common so strip leading white space with:

sed -e "s/^\s*//" test1.txt

Will search all the spaces (including tabs, etc.) at the begining of the lines, and replace them with... nothing!

or something more complex...

sed -e "s/^.*like\(s\)\?/I love/" test1.txt

Now let's assume we have a file test2.txt:

We want to rewrite strings into something like jdoe is "Jown Doe". To achieve that, we instruct sed to replace the first ":" with the string  is ", then we use sed a second time to drop what's after the other ":" (by replacing it with the a double quote ").

sed -e 's/:/ is "/' | sed -e 's/:.*/"/' test2.txt

Which could (and should) be written as sed -e 's/:/ is "/' -e 's/:.*/"/' test2.txt , that's completely equivalent.

Buffers

The above example isn't very readable/maintainable ... but sed make things easier: It is possible to store different part of a matching search regex into some buffers, then use them in the replace part:

sed -e 's/^\(.*\):\(.*\):.*$/\1 is "\2"/' test2.txt

another example with the same sample file:

sed -e 's/^\([^:]*\):\([^:]*\):\(.*\)$/<a class="\3" href="\/~\1">\2><\/a><br>/' test2.txt

Range

It is possible to specify which portion (range) of the file we want to process.

For example, we want to keep the last word of the sentence, but only starting at the second line:

sed -e "2,\$s/^.* //" test1.txt

The range can be expressed as line number, or based on matching regular expression:

sed -e '/John/,/Elisabeth/s/like/love/' test1.txt

Yes, the syntax is /from/,/to/s/search/replace/arg !

Grep'ing

Often, you only want to print the lines where you have (searched and) replaced text:

sed -n -e 's/like/love/p' test1.txt

we have added the option -n to instruct sed it shouldn't print lines by default, then we use "p" at the end of of the search expression ("s///p"), to instruct sed to print the lines that match that expression.

The "d" (delete) command

sed also has a d (delete} command, which purpose is quite similar to grep :

sed -e '/fruits/d' test1.txt

However, It's useful when you need to choose the range of lines to grep:

Drop the lines between the ones containing John and Elisabeth: sed -e '/John/,/Elisabeth/d' test1.txt

Drop the first line: sed -e '1d' test1.txt

Drop the lines, from the line containing John, until the end of the file sed -e '/John/,$d' test1.txt

grep and sed

In most case, you can/should avoid using grep and sed on the same line, since sed can grep files:

Don't write:

But write:

(But there are some exception, especially when grep can discard most of the lines of a large file).

See also

This page is a quick overview of the main sed features. refer to sed official manual (also available as infopage):


?CategoryTutorial, ?CategoryLicenseUnderGpl