ed: Introduction to line editing

1 
1 2 Introduction to line editing
1 ******************************
1 
1 'ed' was created, along with the Unix operating system, by Ken Thompson
1 and Dennis Ritchie. It is the refinement of its more complex,
1 programmable predecessor, 'QED', to which Thompson and Ritchie had
11 already added pattern matching capabilities (⇒Regular
 expressions).
1 
1    For the purposes of this tutorial, a working knowledge of the Unix
1 shell 'sh' and the Unix file system is recommended, since 'ed' is
11 designed to interact closely with them.  (⇒GNU bash manual
 (bash)Top, for details about bash).
1 
1    The principal difference between line editors and display editors is
1 that display editors provide instant feedback to user commands, whereas
1 line editors require sometimes lengthy input before any effects are
1 seen. The advantage of instant feedback, of course, is that if a mistake
1 is made, it can be corrected immediately, before more damage is done.
1 Editing in 'ed' requires more strategy and forethought; but if you are
1 up to the task, it can be quite efficient.
1 
1    Much of the 'ed' command syntax is shared with other Unix utilities.
1 
1    As with the shell, <RETURN> (the carriage-return key) enters a line
1 of input. So when we speak of "entering" a command or some text in
1 'ed', <RETURN> is implied at the end of each line. Prior to typing
1 <RETURN>, corrections to the line may be made by typing either
1 <BACKSPACE> to erase characters backwards, or <CONTROL>-u (i.e., hold
1 the CONTROL key and type u) to erase the whole line.
1 
1    When 'ed' first opens, it expects to be told what to do but doesn't
1 prompt us like the shell. So let's begin by telling 'ed' to do so with
1 the <P> ("prompt") command:
1 
1      $ ed
1      P
1      *
1 
1    By default, 'ed' uses asterisk ('*') as command prompt to avoid
1 confusion with the shell command prompt ('$').
1 
1    We can run Unix shell ('sh') commands from inside 'ed' by prefixing
1 them with <!> (exclamation mark, aka "bang"). For example:
1 
1      *!date
1      Mon Jun 26 10:08:41 PDT 2006
1      !
1      *!for s in hello world; do echo $s; done
1      hello
1      world
1      !
1      *
1 
1    So far, this is no different from running commands in the Unix shell.
1 But let's say we want to edit the output of a command, or save it to a
1 file. First we must capture the command output to a temporary location
1 called a "buffer" where 'ed' can access it. This is done with 'ed''s
1 <r> command (mnemonic: "read"):
1 
1      *r !cal -m
1      137
1      *
1 
1    Here 'ed' is telling us that it has just read 137 characters into
1 the editor buffer - i.e., the output of the 'cal' command, which prints
1 a simple ASCII calendar. To display the buffer contents we issue the
1 <p> ("print") command (not to be confused with the prompt command,
1 which is uppercase!). To indicate the range of lines in the buffer that
1 should be printed, we prefix the command with <,> (comma) which is
1 shorthand for "the whole buffer":
1 
1      *,p
1            June 2006
1      Mo Tu We Th Fr Sa Su
1                1  2  3  4
1       5  6  7  8  9 10 11
1      12 13 14 15 16 17 18
1      19 20 21 22 23 24 25
1      26 27 28 29 30
1 
1      *
1 
1    Now let's write the buffer contents to a file named 'junk' with the
1 <w> ("write") command:
1 
1      *w junk
1      137
1      *
1 
1    Need we say? It's good practice to frequently write the buffer
1 contents, since unwritten changes to the buffer will be lost when we
1 exit 'ed'.
1 
1    The sample sessions below illustrate some basic concepts of line
1 editing with 'ed'. We begin by creating a file, 'sonnet', with some
1 help from Shakespeare. As with the shell, all input to 'ed' must be
1 followed by a <newline> character. Commands beginning with '#' are
1 taken as comments and ignored. Input mode lines that begin with '#' are
1 just more input.
1 
1      $ ed
1      # The 'a' command is for appending text to the editor buffer.
1      a
1      No more be grieved at that which thou hast done.
1      Roses have thorns, and filvers foutians mud.
1      Clouds and eclipses stain both moon and sun,
1      And loathsome canker lives in sweetest bud.
1      .
1      # Entering a single period on a line returns 'ed' to command mode.
1      # Now write the buffer to the file 'sonnet' and quit:
1      w sonnet
1      183
1      # 'ed' reports the number of characters written.
1      q
1      $ ls -l
1      total 2
1      -rw-rw-r--    1 alm           183 Nov 10 01:16 sonnet
1      $
1 
1    In the next example, some typos are corrected in the file 'sonnet'.
1 
1      $ ed sonnet
1      183
1      # Begin by printing the buffer to the terminal with the 'p' command.
1      # The ',' means "all lines".
1      ,p
1      No more be grieved at that which thou hast done.
1      Roses have thorns, and filvers foutians mud.
1      Clouds and eclipses stain both moon and sun,
1      And loathsome canker lives in sweetest bud.
1      # Select line 2 for editing.
1      2
1      Roses have thorns, and filvers foutians mud.
1      # Use the substitute command, 's', to replace 'filvers' with 'silver',
1      # and print the result.
1      s/filvers/silver/p
1      Roses have thorns, and silver foutians mud.
1      # And correct the spelling of 'fountains'.
1      s/utia/untai/p
1      Roses have thorns, and silver fountains mud.
1      w sonnet
1      183
1      q
1      $
1 
1    Since 'ed' is line-oriented, we have to tell it which line, or range
1 of lines we want to edit. In the above example, we do this by
1 specifying the line's number, or sequence in the buffer. Alternatively,
1 we could have specified a unique string in the line, e.g., '/filvers/',
1 where the '/'s delimit the string in question.  Subsequent commands
1 affect only the selected line, a.k.a. the "current" line. Portions of
1 that line are then replaced with the substitute command, whose syntax
1 is 's/OLD/NEW/'.
1 
1    Although 'ed' accepts only one command per line, the print command
1 'p' is an exception, and may be appended to the end of most commands.
1 
1    In the next example, a title is added to our sonnet.
1 
1      $ ed sonnet
1      183
1      a
1       Sonnet #50
1      .
1      ,p
1      No more be grieved at that which thou hast done.
1      Roses have thorns, and silver fountains mud.
1      Clouds and eclipses stain both moon and sun,
1      And loathsome canker lives in sweetest bud.
1       Sonnet #50
1      # The title got appended to the end; we should have used '0a'
1      # to append "before the first line".
1      # Move the title to its proper place.
1      5m0p
1       Sonnet #50
1      # The title is now the first line, and the current address has been
1      # set to the address of this line as well.
1      ,p
1       Sonnet #50
1      No more be grieved at that which thou hast done.
1      Roses have thorns, and silver fountains mud.
1      Clouds and eclipses stain both moon and sun,
1      And loathsome canker lives in sweetest bud.
1      wq sonnet
1      195
1      $
1 
1    When 'ed' opens a file, the current address is initially set to the
1 address of the last line of that file. Similarly, the move command 'm'
1 sets the current address to the address of the last line moved.
1 
1    Related programs or routines are 'vi (1)', 'sed (1)', 'regex (3)',
1 'sh (1)'. Relevant documents are:
1 
1      Unix User's Manual Supplementary Documents: 12 -- 13
1 
1      B. W. Kernighan and P. J. Plauger: "Software Tools in Pascal",
1      Addison-Wesley, 1981.
1