Documented in Volume 1 of the UNIX Programmers Manual.
See /usr/doc/sed on 4.2 BSD systems for additional online documentation on this.
'sed' means 'stream editor'.
% sed G < infile
doublespaces infile and lists to the standard output.
% sed -e p -e 's/.*//'
will insert a blank line after each line of text by printing each line
in the input and then eliminating everything on the line and printing
the (empty) result. This is another way to double-space.
% sed -e 'i\\' inputfile
will replace with a carriage-return, which will
double space inputfile and put the results on the standard output.
Note that the command line will be split into TWO lines by the time you
complete typing it because the newline is a line-feed.
% sed '1,$s/ *$//' infile > outfile
will strip trailing spaces from infile, storing into outfile.
The following Bourne shell script:
#! /bin/sh
find /dirname -print | sort | \
sed -e "s!^/dirname\$!!" \
-e "s!/dirname/!!" \
-e 's:[^/]*/: :g' \
-e '/^$/d'
makes a filetree of the directory named /dirname
by blanking any line which contains only that directory name,
by blanking that directory name on each line,
by casting out blank lines.
From: berge@stolaf.UUCP (Eric Berge)
Organization: St. Olaf College, Northfield MN
I posted the following article for help with a sed script. Several
people have requested that I post the answers which I recieved:
> I was wondering if this is a chronic problem with sed. It
> seems that I cannot get sed to match patterns with an imbedded newline.
> I have talked to some other avid users of sed and they seem to have
> the same problem. According to the documentation, the sequence '\n'
> will match a newline imbedded in a string. So this is what I tried:
>
> I wanted to match:
.ul
followed by anything on the next line
> and convert it to
\fIfollowed by anything on the next line\fR
> so I tried:
sed 's/^\.ul\n\(.*\)$/\\fI\1\\fR/'
> I even tried simple examples to try to get it to work, but to
> no avail. Can anyone help me out?
The problem was that sed cannot match a newline imbedded in a pattern space,
unless you specifically tell sed to join two lines of text so that the
pattern space will have a newline imbedded in it. The key in all responses
was the use of the 'N' command to append the next pattern space to the
current one and them make the search for the imbedded pattern space and
make the appropriate substitution.
The following are some of the various sed scripts which I received to do
the job:
From: Matt Crawford, crawford@anl-mcs.arpa, ihnp4!oddjob!matt
% sed -e '/^\.ul$/N' -e 's/^\.ul\n\(.*\)$/\\fI\1\\fR/' out
From: steve roush, attis - denver
This is not a problem with sed. You've got to get the second line of
text into the pattern space before trying your replace command.
The following should do it:
% sed -e '/^\.ul$/{' -e 'N' -e 's/...\n\(.*\)/\\fI\1\\fR/' -e '}'
From: Alan Bland, druxp!mab, AT&T-ISL Denver
% sed '/^\.ul$/{
N
s/.*\n\(.*\)/\\fI\1\\fR/
}'
From: Lee McMahon Bell Labs, Murray Hill ...ihnp4!research!lem
/^\.ul$/ {
N
s/^\.ul\n/\\fI/
s/$/\\fR/
}
From: Mark Weiser ARPA:mark@maryland UUCP:{seismo,allegra}!umcp-cs!mark
/^\.ul$/N
s/^\.ul\n\(.*\)$/\\fI\1\\fR/
From: George Bergman, decvax!ucbvax!ucbtopaz:gbergman
In "SED - a Non-interactive Text Editor", section 2.2
item 4) describes \n as matching "an imbedded newline character,
but not the newline at the end of the pattern space". Section 1.3
says "Ordinarily the pattern space is one line of the input text,
but more than one line can be read in...using the N command (Sec.3.6)."
So unless you use the N command you can't expect \n to match anything.
The reference to "3.6" (at least in my copy) is apparently a misprint
for 3.4. I find that the following script using the N command
does what you want:
/^\.ul/{N
s/^\.ul\n\(.*\)/\\fI\1\\fP/
}
(I've replaced your \\fR with \\fP, which seems to make more sense.)
Note that ex can get the same effect without any embedded-newline
facility, using the command
g/^\.ul/d|s/.*/\\fI&\\fR
The point is that after a "d", the current line is the line after
the one that was deleted, so the indicated substitution will be
performed on that line. I would very much like multiple-line
pattern-recognition capability in ex, but it isn't needed for this.
I don't really know sed, but since the documentation says that
after deletion no further commands are performed "on the corpse
of the current line...the list of editing commands is restarted
from the beginning" (section 3.1) there is no evident way to achieve
the same result without using N and \n.
The following Bourne shell script will allow lines to be inserted
or to replace input lines by using the a\ (append) and i\ (insert)
functions:
#! /bin/sh
cat xjunk | sed \
-e '1a\
first bunch of lines\
to be appended\
after line number 1' \
-e '5i\
second bunch of lines\
to be outputted \
instead of line number 5'
When executed, it will produce something like this:
file x, line 1
first bunch of lines
to be appended
after line number 1
file x, line 2
file x, line 3
file x, line 4
second bunch of lines
to be outputted
instead of line number 5
file x, line 6
....
From: gbergman@ucbtopaz.CC.Berkeley.ARPA
Subject: sed can do Towers of Hanoi
Newsgroups: net.unix
Organization: Univ. of Calif., Berkeley CA USA
If you put the 60-line sed script [which follows] in a file,
e.g. sed.hanoi, and then do
% sed -f sed.hanoi
and type in, say
:abcd: : :
(notice-- TWO carriage returns-- a peculiarity of sed), then
it will output the sequence of states involved in moving 4 rings,
the largest called "a" and the smallest called "d", from the
first to the second of three towers, so that the rings on any
tower at any time are in descending order of size. You can start with
a different arrangement and a different number of rings, say
:ce:b:ax:
and it will still give the shortest procedure for
moving them all to the middle tower. The rules are: the names
of the rings must all be lower-case letters, they must be input within
3 fields (representing the towers) delimited by 4 colons, such that
the letters within each field are in alphabetical order (= rings in
descending order of size).
For the benefit of anyone who wants to figure out the script,
I will explain that an "internal" line of the form
b:0abx:1a2b3 :2 :3x2
has the following meaning: the material after the three markers :1 :2
:3 represents the three towers; in this case the current set-up is
:ab : :x :. The numbers after a, b and x in these fields indicate
that the next time it gets a chance, it will move a to tower 2, move b
to tower 3, and move x to tower 2. The string after :0 just keeps
track of the alphabetical order of the names of the rings. The b at the
beginning means that it is now dealing with ring b (either about to
move it, or re-evaluating where it should next be moved to).
Although this version is "limited" to 26 rings because of the size
of the alphabet, one could write a script using the same idea in which
the rings were represented by arbitrary [strings][within][brackets], and
in place of the built-in line of the script giving the order of the
letters of the alphabet, it would accept from the user a line giving the
ordering to be assumed, e.g. [ucbvax][decvax][hplabs][foo][bar].
Have fun!
George Bergman
Math, UC Berkeley 94720 USA
ucbvax!ucbcartan!gbergman (if your mailer can
digest a 9-letter name; if not maybe:)
ucbvax!cartan:gbergman or
gbergman%cartan@berkeley
#...............sed.hanoi....................
# cleaning, diagnostics
s/ *//g
/^$/d
/[^a-z:]/{a\
Impermissible characters: use only a-z and ":". Try again.
d
}
/^:[a-z]*:[a-z]*:[a-z]*:$/!{a\
incorrect format: use\
\ : string1 : string2 : string3 :\
Try again.
d
}
/\([a-z]\).*\1/{a\
Repeated letters not allowed. Try again.
d
}
# initial formatting
h
s/[a-z]/ /g
G
s/^:\( *\):\( *\):\( *\):\n:\([a-z]*\):\([a-z]*\):\([a-z]*\):$\
/:1\4\2\3:2\5\1\3:3\6\1\2:0/
s/[a-z]/&2/g
s/^/abcdefghijklmnopqrstuvwxyz/
:a
s/^\(.\).*\1.*/&\1/
s/.//
/^[^:]/ba
s/\([^0]*\)\(:0.*\)/\2\1:/
s/^[^0]*0\(.\)/\1&/
:b
# outputting current state without markers
h
s/.*:1/:/
s/[123]//gp
g
:c
# establishing destinations
/^\(.\).*\1:1/td
/^\(.\).*:1[^:]*\11/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\31/
/^\(.\).*:1[^:]*\12/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\33/
/^\(.\).*:1[^:]*\13/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\32/
/^\(.\).*:2[^:]*\11/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\33/
/^\(.\).*:2[^:]*\12/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\32/
/^\(.\).*:2[^:]*\13/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\31/
/^\(.\).*:3[^:]*\11/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\32/
/^\(.\).*:3[^:]*\12/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\31/
/^\(.\).*:3[^:]*\13/s/^\(.\)\(.*\1\([a-z]\).*\)\3./\3\2\33/
bc
# iterate back to find smallest out-of-place ring
:d
s/^\(.\)\(:0[^:]*\([^:]\)\1.*:\([123]\)[^:]*\1\)\4/\3\2\4/
td
# move said ring (right, resp. left)
s/^\(.\)\(.*\)\1\([23]\)\(.*:\3[^ ]*\) /\1\2 \4\1\3/
s/^\(.\)\(.*:\([12]\)[^ ]*\) \(.*\)\1\3/\1\2\1\3\4 /
tb
s/.*/Done! Try another, or end with ^D./p
d
#............end sed.hanoi....................