Most Linux user need to work on text file for many reasons like editing files, saving commands outputs in file for further use. Sed is very useful, powerful and compact command in Linux which helps in many ways to edit and manipulate text,Can do insertion, deletion, search and replace(substitution). It also support regular expression which make strong to work for text manipulation.So Today in this post, we will see some sed example, which could help us in many ways.

1. Substitution through sed command

Substitution is most used command in sed. it could replace old word,string and regex from new one as per requirement.

Syntax

sed 's/search-pattern/substitute-pattern/'

Description

Single quote used before sed statement is not compulsory for simple word, but for some complex regex which has some meta-characters, it is important to use single quote otherwise it will not behave as required , so i suggest to use single quote with sed commands.

Examples

root@jarvis:~# echo Good night| sed s/night/morning/ 
Good morning

with this above example we know that sed could substitute any word with another one. Let’s have another example with case insensitive.

case intensive

root@jarvis:~# echo Good Night| sed s/night/Morning/i 
Good Morning

In above example we saw how we could make sed search and replace case insensitive.this could be extremely helpful while searching some random pattern. Let’s can we do some regex search and replace with sed.

Using RegEx

root@jarvis:~# echo My cell number  +910054898855| sed 's/[0-9]\{2\}/&-/'
My cell number +91-0054898855

In above example we saw , we use some regex(regular expression) to search and replace and it worked perfectly required. but what if i try to use it without single quote.

root@jarvis:~# echo "My cell number  +910054898855"| sed s/[0-9]\{2\}/&-/
[1] 5727
-su: -/: No such file or directory
root@jarvis:~# sed: -e expression #1, char 11: unterminated `s' command

On my Machine it behave like above, so I suggest to always use single quote with sed.

Globally substitution, Above search and replace is only work for first search in a line, but what if we like to replace in all search in line. like below.

Below we can replace first search

root@jarvis:~# echo good morning , good afternoon , Good evening, Good night | sed -e 's/good/bad/'
bad morning , good afternoon , Good evening, Good night

Through below way, we can replace search all searches

root@jarvis:~# echo good morning , good afternoon , Good evening, Good night | sed -e 's/good/bad/g'
bad morning , bad afternoon , Good evening, Good night

Replace all searches with case insensitive

root@jarvis:~# echo good morning , good afternoon , Good evening, Good night | sed -e 's/good/bad/gI'
bad morning , bad afternoon , bad evening, bad night

we can also target from second search, so first search will remain unchanged.

root@jarvis:~# echo good morning , good afternoon , Good evening, Good night | sed -e 's/good/bad/2gI'
good morning , bad afternoon , bad evening, bad night

But what if i to replace in some range or some random numbers.

Normal as above examples
root@jarvis:~# echo "good morning ,good afternoon ,Good evening ,Good night" | sed '-es/good/bad/'
bad morning ,good afternoon ,Good evening ,Good night


When i like to replace first and second searches in line
root@jarvis:~# echo "good morning ,good afternoon ,Good evening ,Good night" | sed '-es/good/bad/'{2,1}
bad morning ,bad afternoon ,Good evening ,Good night

But when i like to replace third and first occurrence
root@jarvis:~# echo "good morning ,good afternoon ,Good evening ,Good night" | sed '-es/good/bad/I'{3,1}
bad morning ,good afternoon ,bad evening ,Good night

And if we need to change range
root@jarvis:~# echo "good morning ,good afternoon ,Good evening ,Good night" | sed '-es/good/bad/I'{3..1}
bad morning ,bad afternoon ,bad evening ,Good night

Till now we were working with one lines, what if need to do things for a file or command output. we can do things for files as well.

I am going to work on /usr/share/doc/sed/copyright file, i hope everyone working on sed will have this file.

Below will replace first search of you to me.

# sed 's/you/me/' copyright

Below will work on you word only, will not notice you inside your word.It work like complete word space on both sides

# sed 's/<you>/me/' copyright

Below will work search replace every search in line like globally because of using g in sed command

# sed 's/<you>/me/g' copyright | egrep "me|you"

This will limit search for first 15 lines only

# sed '1,15s/you/me/g' copyright | egrep -n "me|you" 

2. Delete Lines through Sed

Sed command could also delete lines containing pattern ,word. This could be done with delete command which help user to manage files, command output with scripts.

Let’s create one sample file to work on sed and see how it works.

root@jarvis:~# cat sample 
Ubuntu 16.04
RedHat 6.10
CentOS
Debian 8
Suse
Solaris
IBM AIX
Fedora
Alpine 
Ubuntu 18.04
Redhat 7.5
Debian 9

Now let’s check syntax for sed delete d flag

Syntax

sed '/pattern/d' sample

Above would delete line contain this pattern

Example

Let’s work on sample file and see how we could work in sed delete d flag.

root@jarvis:~# sed '/Ubuntu/d' sample 
RedHat 6.10
Debian 8
Suse
Solaris
IBM Aix

See Above delete line containing Ubuntu, but what if we like delete with case insensitive, for same we can do below way.

root@jarvis:~# sed '/ubuntu/Id' sample 


root@jarvis:~# sed '/RedHat\|Suse/d' sample

In above command we can see that we deleted line containing Ubuntu word with mentioned ubuntu only (case insensitive). But if we like to particular line number, range of line, first line, last line etc.

Delete First line

# sed '1d' sample

Delete last line

sed '$d' sample 

Delete first and last line

# sed '1d;$d' sample

Delete first four lines

# sed '1,4d' sample

Delete first and fourth line

# sed '1d;4d' sample

Delete all line expect first four line

sed '1,4!d' sample

Delete line start with Capital letter S

# sed '/^S/d' sample

Delete lines ends with digits

# sed '/[0-9]$/d' sample

Delete Blank lines

# sed '/^$/d' sample

Delete lines containing digits only

# sed '/[0-9]$/!d' sample

Delete from second line till line contain Suse

# sed '2,/Suse/d' sample 

Delete between two pattern excluding patterns

# sed '/RedHat/,/Suse/{//!d}' sample

Deleting between two patterns including patterns

# sed '/RedHat/,/Suse/d' sample

Delete all below lines from lines containing pattern including pattern line

# sed '/RedHat/,$d' sample

Delete all above lines from lines containing pattern excluding pattern line

# sed '/Suse/,$!d' sample

3. Print lines through sed p flag

Actually sed print every line, while replacing it print with new content instead old one. But with -n argument, sed could print lines like example below.

Print first line

# sed -n '1p' sample 

Print last line root@jarvis:~# sed -n ‘$p’ sample
Debian 9

Print range of line

# sed -n '1,4p' sample

print multiple lines

# sed -n '1p;4p' sample

print file

# sed -n 'p' sample

Print contain regex or word

# sed -n '/RedHat/p' sample

Print contain digits

# sed -n '/[0-9]/p' sample

print from regex to end of file

# sed -n '/Suse/,$p' sample

Print from first line to regex or word match

# sed -n '0,/Suse/p' sample

Print between regex and word including match

# sed -n '/RedHat/,/Suse/p' sample

4. Slash as a delimiter

Most of sed users only use slash as delimiter like i used in all above examples, but it not required to use it slash only. we can use any other delimiter, it should consistent like below.

root@jarvis:~# sed -n 's|Suse|Windows|p' sample 
Windows

5. & as Matched String

Sometime we need to match regex and need to replace it with some other text include same regex. like below

root@jarvis:~# sed -n 's/^S/Matched--&/p' sample 
Matched--Suse
Matched--Solaris

So in this case we don’t really know what we will find while searching, so we can’t write exact string to replace. Sed could save search string in & and could replace it same. This is really helpful sometime for manipulating text.

6. extended regular expression in sed

Sed could also use extended regular exppression as awk , grep or any other bash command tools. Regex could be used with -r command line options with sed like below

root@jarvis:~# sed -nr '/^[a-zA-Z].*[[:space:]][0-9]$/p' sample
Debian 8
Debian 9

root@jarvis:~# sed -nr '/[a-zA-Z].*[[:space:]][0-9]+.[0-9]$/p' sample
RedHat 7.5

In above command we have used print only strings start with upper or small case alphabet that continue with space and end with two digit number that has point in between. Regex is complete different topic which was covered in other post.

root@jarvis:~# sed -nr '/[Dd]ebian[[:space:]][0-9]$/p' sample
debian 8
Debian 9

In above command we have used print only strings start with upper or small case alphabet that continue with space and end with one digit number in end.