This is the fifth episode of our GNU sed command examples series. This episode contains another 10 command examples covering things such as deleting source code's comments, converting image files (along with ImageMagick tool), and inserting a single or multiple lines to a file. For you just started, we recommend you to read the first until the fourth episode before this one.

Text Examples

text12.txt:

// this is C-style
comment line

// this is the
second line of comment

#include <stdio.h>

int main()

{

printf("This
is the code line\"); // this is a comment right beside a code
line

return 0; // this
is the second comment right beside a return value code

}

text13.txt:

#!/bin/bash

# this is a single
line comment

echo "Hello!"

# this is the last
comment line

text14.txt:

/* this is the
slash-asterisk style of comment

it is multiple
lines of comment

it ends with an
asterisk-slash sequence

*/

#include <stdio.h>

int main()

{

/* this is another
slash-asterisk style of comment

it should be
deleted by GNU sed

*/

printf("Hello\n");

return 0;

}

41. Delete Comment Lines (Double Slash Style)

Command Examples:

sed '/^\/\/.*$/d'
text12.txt

Output Examples:

master@master:/tmp$
sed '/^\/\/.*$/d' text12.txt

#include <stdio.h>

int main()

{

printf("This
is the code line\"); // this is a comment right beside a code
line

return 0; // this
is the second comment right beside a return value code

}

master@master:/tmp$

Explanation:

This command is
basically just a single ‘d’ (delete) command of sed (already
explained in Episode
1). What this command do is to delete all lines beginning with
double slash (`//`). This command has a basic syntax like this:

‘/ /d’

then we add the main
keyword, the double slash:

‘////d’

then we add
backslashes to make sed understand the slashes are literal slashes (this is called escaping):

‘/\/\//d’

then we add `^`
(caret) in the beginning so sed will match the double slash only for
the beginning of line:

‘/^\/\//d’

then we add `.*`
(dot asterisk) so sed will match the following words or a sentence
after the double slash:

‘/^\/\/.*/d’

finally we add `$`
(dollar) so sed understands this whole regex to match a single line
from the beginning to the end:

printf("This
is the code line\"); // this is a comment right beside a code
line

return 0; // this
is the second comment right beside a return value code

}

master@master:/tmp$
sed 's+\([^!]\/\/.*$\)++g' text12.txt

// this is C-style
comment line

// this is the
second line of comment

#include <stdio.h>

int main()

{

printf("This
is the code line\");

return 0;

}

master@master:/tmp$

Explanation:

This example is basically the same with the example number 41. The
only difference is a sequence of regex `[^!]`. This regex tells sed
to match (in this example, to delete) every regex in the beginning of
line. But because there is a single exclamation mark (`!`)
following, the mark of reversal, sed reverses the result to be
to delete every regex matches except
in the beginning of line. So in this example, sed deletes every
side comment, the comment staying beside the code line. See the
printf and return lines.

43. Delete Comment Lines (Hash Style)

Command Example:

sed '/^#[^!].*.$/d'
text13.txt

Output Example:

master@master:/tmp$
sed '/^#[^!].*.$/d' text13.txt

#!/bin/bash

echo "Hello!"

master@master:/tmp$

Explanation:

This example is
special for shell scripting commenting style. This is basically just
the same with example number 41 and 42, except it is much simpler.
There is no backslash so you won’t get confused. The only
difference is a `#` (hash) as a replacement of double slash (`//`).
But be careful, there must be a mark to exclude the line that has `!`
right after the `#`. That mark is the sequence (`[^!]`) from the
example number 42. So this example number 43 deletes all hash-leaded
lines except the line leaded by a single shebang (the `#!`
sequence).

43. Delete Comment Lines (Slash-Asterisk Style)

Command Example:

sed '/\/\*/,/\*\//d'
text14.txt

Output Example:

master@master:/tmp$
sed '/\/\*/,/\*\//d' text14.txt

#include <stdio.h>

int main()

{

printf("Hello\n");

return 0;

}

master@master:/tmp$

Explanation:

This example takes advantage of ‘d’ command double address. The
first address is a regex, and the last address is also a regex. This
means sed will delete all lines between the first and the last
regexes match. The basic syntax is like this:

‘/ /,/ /d’

then we put the first regex with the slash-asterisk and the last
regex with the asterisk-slash:

‘/ /*/,/*/ /d’

finally we escape every slash and asterisk with backslash:

'/\/\*/,/\*\//d'

44. Boolean Operator OR

Command Example:

sed -E -n
'/this|line|return/p' text14.txt

Output Example:

master@master:/tmp$
sed -E -n '/this|line|return/p' text14.txt

/* this is the
slash-asterisk style of comment

it is multiple
lines of comment

/* this is another
slash-asterisk style of comment

return 0;

master@master:/tmp$

Explanation:

This example is a new thing here because it contains `-E` option.
This option makes sed uses the Extended Regular Expression (ERP) so
it can use pipe (`|`) without escaping (or, without backslash). A
single pipe character means logical OR in a regex sequence. So, this
command means print any line containing either “this” or “line”
or “return” keyword. As the result, it prints only the lines
containing either of them.

45. Boolean Operator AND

Command Examples:

sed -n
'/this.*comment/p' text14.txt

sed -n
'/this.*slash.*comment.*/p' text14.txt

Output Examples:

(1)

master@master:/tmp$
sed -n '/this.*comment/p' text14.txt

/* this is the
slash-asterisk style of comment

/* this is another
slash-asterisk style of comment

(2)

master@master:/tmp$
sed -n '/this.*slash.*comment.*/p' text14.txt

/* this is the
slash-asterisk style of comment

/* this is another
slash-asterisk style of comment

master@master:/tmp$

Explanation:

This example is
basically not containing boolean AND at all. But it mimics boolean
AND with the `.*` (dot asterisk) regex. This means, the matched
result should be the line containing both the before and the after
keyword. Hence, you see the result is always [keyword1]...[keyword2]
in one line. The second example shows that you may put any of this
AND sequence (`.*`) to match keywords as many as you want in a single
line.

Please don’t see
them if the output lines confuse you. Just see the command. That
command is basically just one of ImageMagick commands, the `convert`
command. The basic syntax of convert command is very simple:

convert [source]
[destination]

then the single
command sample (PNG to JPEG) is:

convert a.png a.jpeg

now you see that the
single direct converting command is very simple if you know
the [source] file name. But now, we should make `convert` command to
do converting without knowing the [sources] file names.

The `convert` must
do converting for all files in a directory automatically. This
happens with bash looping. And the greatness of bash looping is where
we can put a variable to give `convert` every file name available. So
it will convert the whole files automatically, just like a revolver
gun. So the further command syntax is:

convert
“[source_variable]” “[destination_variable]”

the
[source_variable] is replaced by the `$i` variable as shown in the
example. And the most wonderful is the [destination_variable] is
replaceable with command lines, including echo and
sed, by using escaping apostrophes around. So, we expect sed
to replace every “.png” string into “.jpeg” string, and the
sed output will be the [destination_variable] automatically. Sed can
do it because echo send it the file name (the `$i` content) through
the pipeline (`|`). So in the end, the whole `convert` command
complete, and bash looping will loop that command to every PNG file
in a directory.

This is a new sed
command for our example series. This is ‘i’ command, a GNU sed
extension (so it is available only in GNU sed, not in UNIX sed). This
command in this example has a basic syntax like this:

‘[number]i [text]’
[filename]

then we turn it into
this:

‘3i # THIS IS A
NEW LINE’

finally it will
insert the line after space after the ‘i’ command to the desired
file, to the line number we specified before (line number 3).

50. Insert Multiple Lines

Command Example:

sed '3i # THIS IS A
NEW LINE\n# THIS IS ANOTHER LINE' text13.txt

Output Example:

master@master:/tmp$
sed '3i # THIS IS A NEW LINE\n# THIS IS ANOTHER LINE' text13.txt

#!/bin/bash

# this is a single
line comment

# THIS IS A NEW LINE

# THIS IS ANOTHER
LINE

echo "Hello!"

# this is the last
comment line

master@master:/tmp$

Explanation:

This
example is exactly the same with the example number 49 but the `\n`
sequence. This `\n` is
widely used in many of POSIX related program, as well as any
programming language, as a “newline”. So it will separate the two
sentences with a newline, so the first will be in line number 3
and the later will be in line number 4.