sed

 


 

Record and play a macro in vi

  1. Start recording by pressing q, followed by a lower case character to name the macro
  2. Perform any typical editing, actions inside Vim editor, which will be recorded
  3. Stop recording by pressing q
  4. Play the recorded macro by pressing @ followed by the macro name

To repeat macros multiple times, press : NN @ macro name. NN is a number

# Delete all lines between tags leaving tags:
# Note: Tags with both angle brackets only
sed '/<body>/,/<h1>/{//!d}' $i > tmp.out
mv tmp.out $i

 

If line ends with xyz, join with line below

for i in `ls *.html`
do
### [Ctrl-v] [Ctrl-M]
sed "s,^M,,g" $i > tmp.out
mv tmp.out $i
done

### Join lines that end with string xyz
for i in `ls *.html`
do
sed -e :a -e '/xyz$/N; s/xyz\n/xyz /; ta' $i > tmp.out
mv tmp.out $i
done

for i in `ls *.html`
do
### Join lines that end with lower case letter
sed -e :a -e '/[a-z]$/N; s/\n/ /; ta' $i > tmp.out
mv tmp.out $i
done

 

If line begins with xyz, append to line above

for i in `ls *.html`
do
   sed -e :a -e "$!N;s/\nxyz/xyz/;ta" -e "P;D" $i > $i.tmp
   if [ -s $i.tmp ] 
   then
       mv $i.tmp $i
    else
        echo "Unable to perform operation"
   fi
done

GNU, ssed, sed15+ version...

for i in `ls *.html` do sed ':a; $!N;s/\n//;ta;P;D' $i > $i.tmp mv $i.tmp $i done

 

If xyz found as part of a sentence, move to its own line

for i in `ls *.html`
do
   sed "s/xyz/\\
   xyz/g" $i > $i.tmp
   mv $i.tmp $i
done

 

If xyz found as part of a sentence, move to two lines down

for i in `ls *.html`
do
   sed "s/xyz/\\
   \\
   xyz/g" $i > $i.tmp
   mv $i.tmp $i
done

 

Substitute string between abc and xyz

For example, to change...

...with...

...run...

 

print all except section between 2 regular expressions

 sed "/Regexp_1/,/Regexp_2/d" $i > $i.tmp
 mv $i.tmp $i

 

Delete all between abc and z

sed "s,abc[^z]*z,,g" $i > tmp.out
mv tmp.out $i

For example:

sed "s,<SPAN[^>]*>,,g" $i > tmp.out
mv tmp.out $i

 

Insert line numbers


 # number each line left alignment. (See note on '\t'.)
 sed = #1 | sed "N;s/\n/\t/" >##1

 # number each line (right-aligned)
 sed = #1 | sed "N;s/^/     /;s/ *\(.\{6,\}\)\n/\1  /" >##2

 # number each not blank line
 sed "/./=" #1 | sed "/./N;s/\n/ /" >##3

            #1        ##1               ##2               ##3
            ===       -----------       -----------       -----
            aaa       1       aaa            1  aaa       1 aaa
            bbb       2       bbb            2  bbb       2 bbb
                      3                      3              
            ccc       4       ccc            4  ccc       4 ccc


 # Substitute with a line number. [Capitalize: Solution. January 18, 2000]

 

Add blank lines


 # double space a file
 sed G

 # triple space a file
 sed "G;G"

 # add a blank line every 5 lines (after lines 5, 10, 15, 20, etc.)
 sed "n;n;n;n;G;"

 

Align text


 # Align text flush right on a 50-column width.
 sed -e :a "s/^.\{1,49\}$/ &/;ta"

 Note:
 # The column width can't exceed more than 50 without the possibility of an
 # error message: 'sed: infinite branch loop at line x'

 # Center all text in the middle of a 50-column width.
 # In method 1, spaces are significant.
 # In method 2, spaces at the beginning of the line are discarded in
 # centering the line, and no trailing spaces is add to the end of lines.
 #
 sed -e :a "s/^.\{1,48\}$/ & /;ta" #                     # method 1.
 sed -e :a -e "s/^.\{1,48\}$/ &/;ta" -e "s/\( *\)\1/\1/" # method 2: ^Note.

 

Offset


 # Insert 5 blank spaces at beginning of each line (make page offset)
 sed "s/^/     /"

 

Add Commas


 # Add commas to numeric strings, changing "1234567" to "1,234,567"
 sed -e :a "s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta"

 

Substitution


 # substitute "foo" with "bar"
 sed "s/foo/bar/" #           # replaces 1st instance on each line
 sed "s/foo/bar/4" #          # replaces 4th instance on each line
 sed "s/foo/bar/g" #          # replaces ALL instances

 sed "/foo/s/foo/bar/g" #     # same but executes more quickly
 sed "/baz/s/foo/bar/g" #     # ONLY for lines which contain "baz"

 sed "/baz/!s/foo/bar/g" #    # EXCEPT for lines which contain "baz"

 # substitute "1" with "L", "2" with "i" and so on...
 sed "y/1234/List/" #         # replaces ALL instances

 # substitute only for lines which contain foo_0
 sed "/foo_0/ { s/foo_1/bar_1/g; s/foo_2/bar_2/g; }"

 

Join lines


 sed "$!N;s/\n//" #                      # join pairs of lines side-by-side
 sed :a;$!N;s/\n//;ta; INFILE > OUTFILE  # join all lines (use GNU SED)

 # if a line ends with a K ............. then:
 sed -e :a -e "/K$/N;s/\n//;ta" #        # append the next line to it
 sed -e :a -e "/K$/N;s/\n/ /;ta" #       # - separate with 1 space
 sed -e :a -e "/K$/N;s/.\n//;ta" #       # - delete the K

 # if a line begins with a K ........... then:
 sed -e :a -e "$!N;s/\nK/K/;ta" -e "P;D" # append it to the previous line
 sed -e :a -e "$!N;s/\nK/ /;ta" -e "P;D" # - replace the K with 1 space

 

Reverse


 # reverse order of lines
 sed "1!G;h;$!d" #            # method 1
 sed -n "1!G;h;$p" #          # method 2

 # reverse each character on the line
 sed "/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//"

 

Print line(s) - Absolute


 # beginning at line 7, print every 4th line
 sed -n "7,${p;n;n;n;}"

 # print line number 7
 sed 7!d #                    # method 1
 sed 7q;d #                   # method 2
 sed -n 7p #                  # method 3

 # print lines 3-8 (inclusive)
 sed 3,8!d #                  # method 1
 sed -n 3,8p #                # method 2

 # print all except lines 3-8
 sed 3,8d

 # print lines 9-EOF (inclusive)
 sed 9,$!d

 

Print line(s) - Relative


 sed q #                             # print the first line
 sed 9q #                            # print the first 9 lines
 sed 1,9d #                          # print all except the first 9

 sed -e :a "$q;N;10,$D;ba" #         # print the last 9 lines
 sed -e :a -e "$d;N;2,9ba" -e "P;D" ## print all except the last 9
 sed -n -e :a -e "1,9!{P;N;D;};N;ba" # same
 sed "$!N;$!D" #                     # print the last 2 lines
 sed "$!d" #                         # print the last line
 sed -n "$p"                         # same

 sed "n;d" #                         # print all except every 2th line

 

Print line(s) - Conditional

 # print section of file from regular expression to the end of file 
 sed -n "/Regexp/,$p"

 # print section of file between two regular expressions (inclusive)
 sed -n "/Regexp_1/,/Regexp_2/p"

 # print all except section between 2 regular expressions
 sed "/Regexp_1/,/Regexp_2/d"

 # print only lines which match regexp 
 sed "/AA/!d; /BB/!d; /CC/!d" #             # AA, BB and CC (in any order)
 sed "/AA.*BB.*CC/!d" #                     # AA, BB and CC (in that order)
 sed -e "/AA/b" -e "/BB/b" -e "/CC/b" -e d ## AA, BB or CC
 sed "/AA/!d" #                             # AA
 sed -n "/AA/p"                             # same

 # print 1 line of context before and after regexp with line number
 sed -n -e "/AA/{=;x;1!p;g;$!N;p;D;}" -e h

 # print only lines which do NOT match regexp AA
 sed "/AA/d" #                              # method 1
 sed -n "/AA/!p" #                          # method 2

 # print only lines of 65 characters or longer 
 sed -n "/^.\{65\}/p"

 # print only lines of less than 65 characters.
 sed "/^.\{65\}/d" #                        # method 1
 sed -n "/^.\{65\}/!p" #                    # method 2

 

Paragraph


 # print paragraph if it contains AA (blank line(s) separate paragraphs)
 sed -e "/./{H;$!d;}" -e "x;/AA/!d;"

 # print paragraph if it contains AA and BB and CC (in any order)
 sed -e "/./{H;$!d;}" -e "x;/AA/!d;/BB/!d;/CC/!d"

 # print paragraph if it contains AA or BB or CC
 sed -e "/./{H;$!d;}" -e "x;/AA/b" -e "/BB/b" -e "/CC/b" -e d

 

Deletion


 # delete the last line of each paragraph
 sed -n "/^$/{p;h;};/./{x;/./p;}"

 sed "s/^[ \t]*//" #           # DEL leading blank (spaces, tabs) from FRONT
 sed "s/[ \t]*$//" #           # DELete trailing blank from the END
 sed "s/^[ \t]*//;s/[ \t]*$//" # delete both leading and trailing blank

 sed "$!N;/^\(.*\)\n\1$/!P;D" #                        # consecutive lines.
 sed -n "G;s/\n/&&/;/^\([ -~]*\n\).*\n\1/d;s/\n//;h;P" # nonconsecutive:   
                                                       # some time it fails
 sed "/^$/d" #                 # delete ALL blank lines 
 sed "/./!d" #                 # same

 sed "/./,$!d" #               # DEL leading blank lines at TOP of file
 sed -e :a "/^\n*$/N;/\n$/ba" ## DEL trailing blank lines at the EOF

 sed "/^$/N;/\n$/N;//D" # delete CONSECUTIVE blank lines except the first 2
                        # in each sequence. DEL all blank lines at the EOF.

 sed "/^$/N;/\n$/D" #   # delete CONSECUTIVE blank lines except the first 1
                        # in each sequence. DEL all blank lines at the EOF.
 sed "/./,/^$/!d" #     #                   DEL all blank lines at the TOF:
                                                             (Top-Of-File).

 

Special applications


 # remove nroff overstrikes (char, backspace) from man pages.
 sed "s/.`echo \\\b`//g"    # double quotes required for Unix environment
 sed "s/.^H//g"             # in bash/tcsh, press Ctrl-V and then Ctrl-H
 sed "s/.\x08//g"           # hex expression for sed v1.5

 # get Usenet/e-mail message header
 sed "/^$/q"                # deletes everything after first blank line

 # get Usenet/e-mail message body
 sed "1,/^$/d"              # deletes everything up to first blank line

 # get Subject header, but remove initial "Subject: " portion
 sed "/^Subject: */!d; s///;q"

 # get return address header
 sed "/^Reply-To:/q; /^From:/h; /./d;g;q"

 # parse out the address proper. Pulls out the e-mail address by itself
 # from the 1-line return address header (see preceding script)
 sed "s/ *(.*)//; s/>.*//; s/.*[:<] *//"

 # add a leading angle bracket and space to each line (quote a message)
 sed "s/^/> /"

 # delete leading angle bracket & space from each line (unquote a message)
 sed "s/^> //"

 # remove most HTML tags (accommodates multiple-line tags)
 sed -e :a -e "s/<[^>]*>//g;/Unix shell script. (Modified from a script by Rahul Dhesi.)
 #
 sed "/^end/,/^begin/d" file1 file2 ... fileX | uudecode

 # zip up each .TXT file individually, deleting the source file and
 # setting the name of each .ZIP file to the basename of the .TXT file
 # (under DOS: the "dir /b" switch returns bare filenames in all caps).
 #
 echo @Echo off> zipup.bat
 Dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat

 

Optimize for speed


   sed "s/foo/bar/g" filename         # standard replace command
   sed "/foo/s/foo/bar/g" filename    # executes more quickly

On line selection or deletion in which you only need to output lines
from the first part of the file, a "quit" command (q) in the script
will drastically reduce processing time for large files. Thus:

   sed -n "45,50p" filename           # print line nos. 45-50 of a file
   sed -n "51q;45,50p" filename       # same, but executes much faster

 

 

Other Sed Commands

     

  1. Delete the first line

    sed '1d' filename
     
  2. Remove the last line

    sed '$d' filename

     

  3. Delete lines 3-20
    sed '3,20d' filename

     

  4. Remove all lines with string
    sed '/string/d' filename

     

  5. Remove all lines without string
    sed '/string/!d' filename

     

  6. Delete all lines between string1 and string2
    sed '/string1/,/string2/d' filename

     

  7. Change string1 to string2 on every line that has string3
    sed '/string3/s/string1/string2/g' filename

     

  8. Change the second instance of oldstring to newstring
    sed 's/oldstring/newstring/2' filename

     

  9. Change oldstring to newstring on lines with string. Output only changed lines
    sed -n '/string/s/oldstring/p' filename

     

  10. For every line with string1, put string2 on the beginning of the next line
    sed '/string1/a\
    string2' filename

     

  11. For every line with string1, put string2 on the beginning of the preceding line
    sed '/string1/i\
    string2' filename

     

  12. For every line with foo, create a new line with bar underneath
         
    sed "/foo /a\\
    bar " $i
    

     

  13. Delete all lines between string1 and string2 and replace with newstring
    sed 's/string1/,/string2/c\
    newstring' filename