Source files and build scripts for my personal website
git clone
Download | Log | Files | Refs | README (12852B)

      1 # The man page reading club: ed(1)
      3 *This post is part of a [series](../../series)*
      5 I enjoyed writing a little introduction at the beginning of every
      6 post of this series, but I am running out of ideas. I am not much
      7 of fiction writer. I'll skip this time, maybe I'll get back to doing
      8 it in the future.
     10 For this episode I chose to explore ed,
     11 [the standard editor](
     12 This little piece of software first appeared in the very first
     13 version of UNIX, in the late '60s. Back then, the most common way
     14 to interact with a computer was via a
     15 [teletype]( This meant
     16 that, in order to edit a file, you could not simply show a screenful
     17 of text and modify it interactively.
     19 As we will see in this post, the way you modify your text files
     20 with ed is by running commands, as you would in your usual
     21 [shell](../2022-09-13-sh-1).  You might wonder why in the world you
     22 should be interested in using this over a more human-friendly text
     23 editor. There are at least a couple of reasons:
     25 1. You find yourself in a very limited environment (e.g. some ebedded
     26    OS) where ed is the only editor available.
     27 2. You want to edit a text file as part of a shell script - you can
     28    find an example in my [last blog entry](../2022-11-23-git-host).
     30 ## ed(1)
     32 *Follow along at
     33 [](*
     35 The first section explains a few fundamental things.
     37 First of all, ed can be invoked with a file as an argument.  The
     38 given file is copied into a *buffer*, and changes are written to
     39 it only when the user issues a `w` command.
     41 ed reads every line the user inputs and tries to interpret it as a
     42 command. The general form for an ed command is
     44 ```
     45     [address[,address]]command[parameters]
     46 ```
     48 Where the (optional) addresses specify a range of lines over which
     49 the command has to operate. See the **Line addressing** section
     50 below for more info.
     52 Some commands allow you to switch to *input mode*, where ed reads
     53 text without trying to interpret it as a command - usually for the
     54 purpose of inserting it in your file - until a line with a single
     55 dot `.` character is read.
     57 There are only two command line options for ed: `-s` to suppress
     58 diagnostic messages and `-p prompt` to specify a prompt string for
     59 its command line.
     61 ### Line addressing
     63 Every command operates on one or more lines. The default is the
     64 *current line*, which is usually set to be the last line affected
     65 by the last command. For example, after opening a file, the current
     66 line is set to its last line.
     68 You can specify the line(s) on which a command shall operate by
     69 prepending one or two *addresses* separated by a comma or a semicolon.
     70 The difference is the following:
     72 ```
     73      Each address in a comma-delimited range is interpreted relative to the
     74      current address.  In a semi-colon-delimited range, the first address is
     75      used to set the current address, and the second address is interpreted
     76      relative to the first.
     77 ```
     79 For example, let's say you are on line 3. Then the address range
     80 `5,+4` selects the lines from 5 to 7 (3+4), while `5;+4` selects 5
     81 to 9 (5+4).
     83 But what is a valid address, actually? Besides simply specifying a
     84 line number, there are a variety of ways to address line: For
     85 example, `.` refers to the current line and `$` to the last line
     86 of the file. As we have seen, you can also specify relative addresses
     87 in the form `-n` or `+n`.  You can also search for a line containing
     88 a specific patern:
     90 ```
     91      /re/    The next line containing the regular expression re.  The search
     92 	     wraps to the beginning of the buffer and continues down to the
     93 	     current line, if necessary.  The second slash can be omitted if
     94 	     it ends a line.  "//" repeats the last search.
     95 ```
     97 For more infor about regular expressions, see
     98 [re_format(7)](
     99 (or perhaps my next blog entry?). Using question marks instead of
    100 slashes (like this: `?re?`) searches backwards.
    102 ### Commands
    104 ed offers a lot of commands to manipulate text. If you are familiar
    105 with other UNIX editors such as vi or sed, you may recognize many
    106 of them.
    108 As usual, they are listed in alphabetic order in the manual page,
    109 so I took the liberty of re-arranging them into groups. I'll have to
    110 skip or just briefly mention some of them, otherwise I might just
    111 as well copy the whole manual page here.
    113 **Address-only commands**
    115 Specifying an address only, without a command, changes the current
    116 line to the (last) addressed line and it prints it. The default is
    117 the next line, i.e. if you just press enter ed prints out the next
    118 line and sets it as the current line.
    120 **Printing lines**
    122 The command `p` prints the addressed line. The command `n` does the
    123 same, but it also prints line numbers. `l` is the same as `p`, but
    124 special characters (e.g. new lines) are made visible.
    126 Most commands accept a *print suffix* `p`, `l` or `n` that instructs
    127 ed to print the last line affected by the command. Thus, the three
    128 printing commands can be also seen as an *address-only command*
    129 followed by a print suffix.
    131 **Basic editing**
    133 The commands `a` and `i` toggle *input mode* to let you insert text
    134 after (**a**ppend) or before (**i**nsert) the last line addressed.
    135 Usually you want to address a single line, often the current line,
    136 when using one of these commands.
    138 The commands `d` and `c` can be used to **d**elete or **c**hange
    139 the addressed lines. The latter is equivalent to `d` followed by an
    140 `a` command.
    142 **Copying, moving and joining lines.**
    144 The commands `t` and `m` operate on a range and take an extra single
    145 address (which can be `0`) as a parameter, and copy (**t**ransfer)
    146 or **m**ove the addressed lines to that location. For example the
    147 command `2,4t0` will copy the 2nd, 3rd and 4th lines to the beginning
    148 of the file.
    150 If you want to join multiple lines in one you can use the `j` command.
    152 **Text substitution**
    154 The `s` command is one of the most powerful ed offers, but also one
    155 of the most complex. It allows you to replace a piece of text, or
    156 any arbitrary pattern defined by a regular expression, with whatever
    157 you like.
    159 It comes in three variants:
    161 ```
    162 (.,.)s/pattern/text/
    163 (.,.)s/pattern/text/g
    164 (.,.)s/pattern/text/n
    165 ```
    167 Where `pattern` is a regular expression and `text` is simple text.
    168 The first form replaces only the first occurrence of `pattern` in
    169 each selected line, while the second replaces every occurrence. In
    170 the last form, `n` must be a number, and only the n-th occurrence
    171 is replaced.
    173 There are some special characters that can be used: for example, a
    174 single `&` in `text` is equivalent to the currently matched text.
    175 If `text` consists of a single `%`, the `text` argument of the last
    176 `s` command issued is used.
    178 You may escape any character in `text`, including newlines, by
    179 prepending a backaslash. To avoid escaping slashes to death, keep
    180 in mind that you can use any other character, for example a `|`,
    181 instead of `/` in the `s` command.
    183 Finally, a simple `s` command, without pattern or text, repeats the
    184 last substitution issued.
    186 Let's put this all together with a single example. We have a file
    187 that looks like this:
    189 ```
    190 This is the first line
    191 Another line, called the second line
    192 /A third line, with boundaries/
    193 Let's make it four
    194 ```
    196 And run the following ed commands:
    198 ```
    199 1/s/t/T/
    200 1/s/T/&&/g
    201 2/s/l/%/
    202 1,3s
    203 3s|/|\||g
    204 ```
    206 The result is:
    208 ```
    209 TThis is TThe first lline
    210 Another llline, called the second line
    211 |A third lline, with boundaries|
    212 Let's make it four
    213 ```
    215 Understanding why you get this is left as an exercise for the reader ;-)
    217 **Multiple commands on selected lines**
    219 The commands `g` and `G` are also quite powerful. With
    221 ```
    222 (.,.)g/pattern/command-list
    223 ```
    225 you can specify a list of commands to be executed on every line
    226 matching the regular expression `pattern`. The commands in the list
    227 are each on their own line, ended with a backslash. The command `G`
    228 is essentially an interactive version of `g`. Check the man page
    229 for more details!
    231 **Marks**
    233 You can mark a line with a single lowercase letter (say x) using
    234 the command `[address]kx`. What for, you might ask? Well, when
    235 talking about addresses I omitted to tell you that you can also
    236 refer to a marked line using `'x`.  You only have 26 marks at your
    237 disposal, and one is only deleted when the line it marks is modified,
    238 so use them wisely!
    240 **Reading files and commands**
    242 You can use the `r` command to insert the content of a file (with
    243 `r filename`) or the output of a command (with `r !command`) after
    244 the current line. This is the same as the `r` command of vi, which
    245 I have discussed in a [previous blog entry](../2022-09-05-man-col).
    247 **Undo**
    249 Use the `u` command to undo the last command. Using `u` twice
    250 undoes the undo.  No editing history for you, sorry.
    252 **File management**
    254 From inside ed, you can use `e filename` to open a new file (**e**dit),
    255 `w` to save your changes to the current file (**w**rite) and `q`
    256 to quit.  These commands have an upper-case variant (`E`, `W`, and
    257 `Q`) that can be used to ignore errors (e.g. quit without saving).
    259 The command `wq` can be used as a shortcut for saving and closing.
    261 ### ?
    263 ed is infamously terse with its error messages. Indeed, whatever
    264 error you make, you are going to be faced with the following
    265 informative line:
    267 ```
    268     ?
    269 ```
    271 But don't worry: the command `h` shows a more verbose description
    272 of the last error. You can use the `H` command to toggle verbose
    273 error messages for the whole session.
    275 ## An example session
    277 Let's write an *Hello world* text file using ed!
    279 Let's start by calling ed with a reasonable prompt, to make our
    280 life easier.
    282 ```
    283 $ ed -p 'ed > ' hellow.txt
    284 ```
    286 And let's open a (new) file:
    288 ```
    289 ed > e hellow.txt
    290 ```
    292 Don't worry about the (unusually verbose!) error message. The file
    293 does not exist yet, but it will be created when we save our work
    294 with `w`.  Now let's add a line of text:
    296 ```
    297 ed > a
    298 Hello, wolrd!
    299 wq
    301 ```
    303 Wait, why is ed still open? And why is it not showing the `ed > `
    304 prompt?  Oh right, we forgot to end the input mode by entering a
    305 single dot!
    307 ```
    308 .
    309 ed >
    310 ```
    312 Ok, now we are back in business. But we have to remove the `wq`
    313 line we entered by mistake:
    315 ```
    316 ed > /wq/d
    317 ```
    319 Let's check that we have written what we intended to by printing
    320 the content of the file:
    322 ```
    323 ed > 1,$n
    324 1       Hello, wolrd!
    325 ```
    327 Oh no, there is a typo! No big deal, we can fix it:
    329 ```
    330 ed > 1s/lr/rl/
    331 ```
    333 And now that we are done, we can close our file:
    335 ```
    336 ed > q
    337 ?
    338 ```
    340 Wait, what's going on? Let's check:
    342 ```
    343 ed > h
    344 warning: file modified
    345 ```
    347 Oh right, we need to save.
    349 ```
    350 ed > wq
    351 ```
    353 And now we are done!
    355 ## I/O redirection magic
    357 As all other basic UNIX utilities, ed can be used non-interactively
    358 by using input / output redirection. As an example, consider the
    359 interactive session above. The input we fed to ed was:
    361 ```
    362 e hellow.txt
    363 a
    364 Hello, wolrd!
    365 wq
    366 .
    367 /wq/d
    368 1,$n
    369 1s/lr/rl/
    370 q
    371 h
    372 wq
    373 ```
    375 If we save (a stripped down version of) the text above in a file
    376 called `edcommands.txt`
    378 ```
    379 a
    380 Hello, wolrd!
    381 wq
    382 .
    383 /wq/d
    384 1s/lr/rl/
    385 wq
    386 ```
    388 and run
    390 ```
    391 $ ed -s hellow2.txt < edcommands.txt
    392 ```
    394 We should obtain a file `hellow2.txt` identical to `hellow.txt`. I
    395 say "should" because apparently there is a little caveat: when used
    396 non-interactively, ed exits on the first error it encounters. This
    397 also happens with the `No such file or directory` error that we get
    398 at the beginning, if a file `hellow2.txt` does not exist yet. We
    399 just have to create one in advance, for example with `touch
    400 hellow2.txt`, and run again the ed command above.
    402 ## Conclusions
    404 ed was designed in a time when the computer-human interaction was
    405 a bit different from now, and it shows. However, its language is
    406 pleasantly consistent: every action you want to perform is expressed
    407 in the address-command-parameters form. This makes it easy to learn
    408 and boring, which is a good thing. Such consistency is much harder
    409 to achieve in the 2D graphical world - which includes
    410 [TUIs](
    412 At the beginning of the post I have mentioned two use cases for a
    413 software like ed in the present day: being forced into a limited
    414 environment and using it in non-interactive mode. But there is at
    415 least another one: for visually impaired users, modern computer
    416 interfaces are largely inaccessible, as they can't look at a wall
    417 of text and pictures to figure out where the stuff they want to
    418 work on is. On the other hand, an editor like ed does not overwhelm
    419 users with visual output and does not require them to keep in mind
    420 more than one line at the time. If you are interest in this topic
    421 I highly suggest reading the article
    422 [The command line philosophy](
    423 by Karl Dahlke, the author of [edbrowse](
    425 *Next in the series: [dc(1)](../2023-03-30-dc)*