sed
Record and play a macro in vi
- Start recording by pressing q, followed by a lower case character to name the macro
- Perform any typical editing, actions inside Vim editor, which will be recorded
- Stop recording by pressing q
- 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
donefor 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 donefor 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...
The deleteChain command deletes
...with...
Delete
...run...
for i in `ls *.html`
do
sed "s,The .* command delete,Delete," $i > tmp.out
mv tmp.out $i
done
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 $iFor 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
- Delete the first line
sed '1d' filename- Remove the last line
sed '$d' filename
- Delete lines 3-20
sed '3,20d' filename
- Remove all lines with string
sed '/string/d' filename
- Remove all lines without string
sed '/string/!d' filename
- Delete all lines between string1 and string2
sed '/string1/,/string2/d' filename
- Change string1 to string2 on every line that has string3
sed '/string3/s/string1/string2/g' filename
- Change the second instance of oldstring to newstring
sed 's/oldstring/newstring/2' filename
- Change oldstring to newstring on lines with string. Output only changed lines
sed -n '/string/s/oldstring/p' filename
- For every line with string1, put string2 on the beginning of the next line
sed '/string1/a\
string2' filename
- For every line with string1, put string2 on the beginning of the preceding line
sed '/string1/i\
string2' filename
- For every line with foo, create a new line with bar underneath
sed "/foo /a\\ bar " $i
- Delete all lines between string1 and string2 and replace with newstring
sed 's/string1/,/string2/c\
newstring' filename