To Index

 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....................
 

To Index