ED(1)ED(1)NAMEed - line oriented text editor
SYNOPSISed [ -p prompt-string ] [ -s ] [ -v ] [ filename ]
Ed is a standard text editor.
Ed is a powerful line oriented editor. Although ex(1)/vi(1) have gained
popularity, ed still maintains advantages over them. Most notable
points are the W command (see below) (which is not part of
ex(1)/vi(1)), the smaller executable size (you can often be editing
before the others finish loading), and the better response when editing
from slow terminals or across low baud data lines. Ed continues to be
used by many system utilities.
When a filename is present ed starts by simulating an e command (see
below) If no filename is present ed starts with an empty buffer. The
option -p allows for the setting of a prompt string in ed. The option
-s suppresses the printing of explanatory output (from the commands e,
E, r, w, W and wq; see below) and should be used with a script. The -v
option will display a message of which mode (BSD or POSIX) ed as been
set locally. This is useful for determining the described behavior
Ed performs all changes to a copy of the file which is contained in a
buffer. For the changes to have an effect one of the write commands (
w, W, wq, or Wq) must be issued.
The contents of the buffer can changed by issuing commands that are
lead by zero, one, or two addresses. All commands are alphabetically
listed below with their parameter structures if applicable; trailing
structures not described with commands are regarded as erroneous. Com‐
mands that accept zero addresses regard the presence of any address as
Ed works in two modes: command, and input. The two modes are exclusive
of each other. While in command mode ed accepts commands that display,
modify, or give information about the buffer. While in input mode ed
accepts lines of text to be added to the buffer.
Addressing in ed specifies one or more lines contained in the buffer.
For commands that expect at least one address, and none are given,
default addresses will be used. Using addresses in ed involves under‐
standing that during the execution of most ed commands that a current
line ( current) exists. Current (as a rule of thumb) is the location
in the buffer that the last command issued affected; some commands do
not affect current. Each command description (below) describes its
affects on current as the affect will vary depending under which com‐
pile option (BSD or POSIX) ed was compiled under. Addresses can be
divided into three cases: one address (single address), two addresses
(an address pair), and special address forms.
For the first two cases an address is formed with the use of:
1. A positive decimal integer (e.g. 123) indicating a line number
in the buffer. Line number 1 is the first line in the buffer.
2. The `.' character indicating the current line (current).
3. The `$' character which indicates the last line in the buffer.
4. A regular expression (RE) enclosed with `/'s as delimiters (i.e.
/RE/). This causes a forward search to the first occurrence of
the specified RE. The address will then become this line. The
character sequence \/ escapes the forwardslash from being a
delimiter. The search will wrap from the bottom of the buffer
to the top of the buffer if need be. Ed RE's are, outside of
this document, now refered to as basic regular expressions.
Basic regular expressions (BRE's), traditionally described in
ed(1) are now fully described in regex(7). BRE's are, for the
most part, the same as the old RE's - the name has changed and
the expressions extended to meet POSIX 1003.2 specifications.
(See the search command for more details.)
5. A RE enclosed with `?'s as delimiters (i.e. ?RE?). This will
cause a backward search to the first occurrence of the specified
BRE. The address will then become this line. The character
sequence \? escapes the questionmark from being a delimiter.
The search will wrap from the top of the buffer to the bottom of
the buffer if need be. (See the search command for more
6. A line previously marked by the `k' command (see below). `x
addresses the line marked by the single lower-case letter `x'
(from the portable character set in the range a-z).
7. An address of the form 1-6 followed by a `+' followed by an
integer number, n, specifies the line to be addressed is n lines
after the address of the form 1-6. If the address starts with a
`+' then by default the addressed line is taken with respect to
current (equivalent to `.'; form 2). If no integer number is
given then 1 is added to the address. Hence, if more than one
`+' is given in a sequence, with no integer number following, 1
is added to the address for each `+'. Therefore, +++ is eqiva‐
lent to +3, but +++1 is equivalent to +1.
8. An address of the form 1-6 followed by a `-' followed by an
integer number, n, specifies the line to be addressed is n lines
before the address of the form 1-6. If the address starts with
a `-' then by default the addressed line is taken with respect
to current (`.'; form 1). If no integer number is given then 1
is subtracted from the address. Hence, if more than one `-' is
given in a sequence, with no integer number following, 1 is sub‐
tracted from the address for each `-'. Therefore, --- is eqiva‐
lent to -3, but ---1 is equivalent to -1. For backward compati‐
bility `^' is the equivalent to `-'.
9. A `,' (comma) may be used to separate two addresses of the form
1-8 to create an address pair. The first address must occur no
later in the buffer than the second address to be legal.
10. A `;' (semicolon) may be used to separate two addresses of the
form 1-8 to create an address pair. With this form the second
address is evaluated with respect to and after the first address
has been evaluated. This is useful when addresses of the forms
2-8 are used. The first address must occur no later in the buf‐
fer than the second address to be legal.
NOTE: Addresses of the forms 7 and 8 cannot be followed by addresses
of forms 2-6; it is an error.
The following are special address forms that cannot be combined with
any of the address forms listed above. A `,' by itself represents the
address pair `1,$'. Likewise `%' by itself represents the address pair
`1,$'. A `;' by itself represents the address pair `.,$'.
The ed commands listed below default to the addresses prefixing the
commands. Commands without default addresses accept zero addresses.
The parentheses with the default addresses are not part of the address;
they are used to show that the addresses are default.
Generally only one command appears on a line at a time. However, many
of the commands may be suffixed by `l', `n', or `p', in which case the
current line is printed in the manner discussed below. These suffixes
may be combined in any order.
Append text after the addressed line. A `.' in the first column
followed immediately by a <newline> places ed back in command mode
- the `.' is not included in the text. Line 0 is legal for this
command; text will be placed at the top of the buffer. Current is
the last line appended (or the addressed line if no text given).
Change text on the addressed line(s). The addressed lines are
deleted before ed is placed in input mode. A `.' in the first col‐
umn followed immediately by a <newline> places ed back in command
mode - the `.' is not included in the text. Current is the new
last line appended (or if no text is given the line after the
addressed line deleted).
Delete the addressed line(s) from the buffer. Deleted lines may be
recovered with the undo command (u; see below). Current is the
line after the last addressed line deleted.
Edit the new file `filename'. The buffer is cleared and the new
file is placed in the buffer. If the buffer has been modified
since the last write command ed will issue a warning (`?'); a sec‐
ond issuing of the command will be obeyed regardless. The number
of characters read is printed (unless -s is specified at startup).
If `filename' is missing, the remembered name is used. If `file‐
name' is lead by ! then it shall be interpreted as a shell command
to be executed, from which the standard output will be placed into
the buffer; `filename' will be non-remembered. Undo will not
restore the buffer to its state before the edit command. Current
is the last line in the buffer (`$').
E works the same as e except if the buffer has been modified no
warning is issued.
Print the remembered filename. If `filename' is specified the
remembered filename will be set to `filename'. If `filename' is
lead by ! then it shall be interpreted as a shell command to be
executed, from which the standard output will be used as the new
remembered filename. Current is unchanged.
(1,$)g/regular expression/command list
The global command first marks all lines matching the regular
expression. For each matching line, the command list is executed.
At the start of each command list execution, current is set to
equal that line; current may change as each command in the command
list is executed for that line. The first command of the command
list begins on the same line as the global command. Generally, in
the command list one command occupies a line. Thus to have multi‐
ple commands in the command list it is necessary to escape the
<newline> at the end of each line so that the global command does
not interpret it as an indication that the command list entry has
ended. The <newline> is escaped by proceeding it with a backslash
(`\'). Similarly with the commands that set ed into input mode
the <newlines> of the entered text need to be escaped. If the `.'
used to end input mode is the last line of the command list the
<newline> following the `.' need not be escaped, or the `.' may be
omitted entirely. Commands in the command list can affect any
line in the buffer. For the behaviour of each ed command within a
command list refer to the information on the individual command,
particularly s and !. The commands g, G, v, V, and ! are permit‐
ted in the command list, but should be used with caution. The
command list defaults to p if left empty (i.e. g/RE/p). For the
regular expression the delimiters can be any characters except for
<space> and <newline>; delimiters within a regular expression can
be escaped with a backslash preceeding it.
The interactive global command works similar to g. The first step
is to mark every line which matches the given regular expression.
For every line matched it will print this line, set current to
this line, and accept one command (not including a, c, i, g, G, v,
and V) for execution. The command can affect any line in the buf‐
fer. `%' by itself executes the last non-null command. A return
by itself will act as a null command. Current will be set to the
last line affected by the last successful command input. If no
match or an input command error occurs current will be set to the
last line searched by G. G can be prematurely ended by `ctrl-C'
(SIGINT). For the behaviour of each ed command within a command
list refer to the information on the individual command, particu‐
larly s and !.
The help command displays a message explaining the most recent
command error (indicated by `?'). Current is unchanged.
This toggles on or off the automatic display of messages explain‐
ing the most recent command error in place of `?'. Current is
The insert command places ed in input mode with the text being
placed before the addressed line. Line 0 is invalid for this com‐
mand. A `.' in the first column followed immediately by a return
places ed back in command mode - the `.' is not included in the
text. Current is the last line inserted. If no text is inserted
then current is the addressed when ed is compiled for POSIX; com‐
piled for BSD, current is the addressed line -1.
The join command joins the addressed lines together to make one
line. If no addresses are specified current and current+1 lines
are joined. If one address only is given then no join is per‐
formed. Current becomes that line if ed has been compiled under
the BSD option; if compiled under the POSIX option current is
( . )kx
The mark command marks the addressed line with label x, where x is
a lowercase letter from the portable character set (a-z). The
address form `x will refer to this line (address form 6 above).
Current is unchanged.
The list command prints the addressed lines in an unambiguous way:
non-graphic characters are printed in three-digit octal preceded
by a \ unless they are one of the following in which case they
will be printed as indicated in the brackets: backslash (`\\'),
horizontal tab (\t), form feed (\f). return (\r), vertical tab
(\v), and backspace (\b). Long lines will be broken based on the
type of terminal currently in use and will likely be ragged at the
right side if text and octal are mixed on the same line. Current
is set to the last line printed. The l command may be placed on
the same line after any command except (e, E, f, q, Q, r, w, W, or
The move command moves the addressed lines in the buffer to after
the address a. Line 0 is valid as the address a for this command.
Current is the location in the buffer of the last line moved.
The number command prints the addressed lines preceding the text
with the line number. The n command may be placed on the same
line after any command except (e, E, f, q, Q, r, w, W, or !).
Current is the last line printed.
The print command prints the addressed lines. The p command may
be placed on the same line after any command except (e, E, f, q,
Q, r, w, W, or !). Current is the last line printed.
This command is a synonym for p if ed has been compiled under the
BSD option. If ed has been compiled under the POSIX option then
the prompt is toggled on or off. Current is unchanged when com‐
piled under the POSIX option. The default prompt is "*" if not
specified with the -p option at startup. The prompt is initially
off unless the -p option is specified.
q The quit command causes ed to exit. If the entire buffer (1,$) has
not been written since the last modification ed will issue a warn‐
ing once (`?'); a second issuing of the command will be obeyed
Q Q works the same as q except if the buffer has been modified no
warning is issued.
The read command reads in the file `filename' after the addressed
line. If no `filename' is specified then the remembered filename
is used. Address 0 is valid for this command. If read is success‐
ful then the number of characters read is printed (unless the -s
option is specified). If `filename' is lead by ! then it shall be
interpreted as a shell command to be executed, from which the
standard output will be placed in the buffer; `filename' will be
non-remembered. Current is the last line read.
( ., .)s/regular expression/replacement/flags
The substitute command searches for the regular expression in the
addressed lines. On each line in which a match is found, matched
strings are replaced by the replacement as specified by the flags
(see below). If no flags appear, by default only the first occur‐
rence of the matched string in each line is replaced. It is an
error if no matches to the RE occur.
The delimiters may be any character except <space> or <newline>.
The delimiter lead by a \ will escape it to be a literal in the RE
An ampersand, `&', appearing in the replacement will equal the
string matching the RE. The `&'s special meaning is supressable
by leading it with a `\'. When `%' is the only replacement char‐
acter in replacement the most recent replacement is used. The
`%'s special meaning is supressable by leading it with a `\'.
The characters `\n' (where n is a digit 1-9) is replaced by the
text matching the RE subexpression n (known as backreferencing).
S may be used to break lines by including a <newline> in replace‐
ment preceeded by a backslash (`\') to escape it. Replacement can
continue on the next line and can include another escaped <new‐
The following extention should not be included in portable
scripts. When spliting lines using s within the global commands
(g, G, v, or V) the <newline> in the replacement string must be
escaped by preceding it with `\\\' (three adjacent `\'s - the
first `\' escapes the second `\' so that it is passed to s to
escape the <newline> passed by the global command; the third `\'
is to escape the <newline> so that the global command list contin‐
ues). [N.B. Other ed's do not allow line splitting within the
The flags may be any combination of:
count in each addressed line replace the count-th matching occur‐
g in each addressed line replace all matching occurrences.
When count and g are specified together inclusively replace
in each addressed line all matches from the count-th match
to the end of line.
l write the line after replacement in the manner specified by
the l command.
n write the line after replacement in the manner specified by
the n command.
p write the line after replacement in the manner specified by
the p command.
The following special form should not be included in portable
scripts. This form is maintained for backward compatibility and
is extended to dovetail into the above forms of s. S followed by
no delimiters repeats the most recent substitute command on the
addressed lines. S may be suffixed with the letters r (use the
most recent RE rather than the last RE used with s), p (complement
the setting of the any print command (l, n, p) suffix from the
previous substitution), g (complement the setting of the g suffix)
or N (negate the previous count flag). These modifying letters
may be combined in any order (N.B. multiple use of the modifying
letters may cause them to be interpreted as delimiters).
Current is set to the last line search (BSD) or where the last
replacement occurred (POSIX).
The transcribe command copies the addressed lines in the buffer to
after the address a. Address 0 is valid as the address a for this
command. Current is the last line transcribed.
The undo command nullifies the most recent buffer modifying com‐
mand. Buffer modifying commands undo works on are a, c, d, g, G,
i, j, m, r, s, t, u, v, and V. Marks set by the k command will
also be restored. All commands (including nested g, G, v, and V
commands within the g or v) that undo works on are treated as a
single buffer modification. Current is set to the line it
addressed before the last buffer modification.
(1, $)v/regular expression/command list
The global non-matching command performs as the g command does
except that the command list is executed for every line that does
not match the RE.
(1, $)V/regular expression/
The interactive global non-matching command is the same as the G
except that one command will be accepted as input with current
initially set to every line that does not match the RE.
(1, $)w [filename]
The write command writes the addressed lines to the file `file‐
name'. If no `filename' is specified then the remembered filename
is used. If no addresses are specified the whole buffer is writ‐
ten. If the command is successful, the number of characters writ‐
ten is printed (unless the -s option is specified). If `filename'
is lead by ! then it shall be interpreted as a shell command to be
executed which will accept on its standard input the section of
the buffer specified for writting. Current is unchanged.
(1, $)W [filename]
W works as the w command does except the addressed contents of the
buffer are appended to `filename' (or the remembered filename if
`filename' is not specified). If `filename' is lead by ! then W
will act exactly as the w command. Current is unchanged.
(1, $)wq [filename]
wq works as the w command does with the addition that ed exits
immediately after the write is complete. Current is unchanged.
Wq works as the W command does with the addition that ed exits
immediately after the appended write is complete. Current is
Scroll through the buffer. Starting from the addressed line (or
current+1) print the next 22 (by default or n) lines. The n is a
sticky value; it becomes the default number of lines printed for
successive scrolls. Current is the last line printed.
($)= Print the number of lines in the buffer. If an address is pro‐
vided (in the forms 1-8 above) then the line number for that line
will be printed. Current is unchanged.
The command after the ! is executed by sh(1) and the results are
printed. A `!' is printed in the first column when execution has
completed (unless the -s option has been specified). A `!' imme‐
diately after ! repeats the last shell command. An unescaped `%'
represents the remembered filename. Commands to sh(1) can have
several lines by escaping the <newline> with a `\' immediately
before it. The line continuation character for sh(1), `\', can be
included on a line provided that it is escaped by a `\' immedi‐
ately before so that ed passes it literally to sh(1): `\\'. It is
implicit that for the command line that the sh(1) line continua‐
tion character is on that the <newline> will be escaped (e.g.
`\\\<newline>'). This behavior can be used within global command
lists. However, an additional `\' must be added so that the ! com‐
mand continuor is passed to ! - it must occur immediately before
the global command's continuor. Therefore, the ! command continua‐
tion sequence in a global command list will appear as `\\\'
(explanation as with sfR). The line continuation character for
sh(1) needs no additional escaping (since it it not dependant on
<newline> being adjacent) - hence, the sequence in a global com‐
mand list with a line continuation will appear as `\\\\\<new‐
Current is unchanged.
The search command searches forward, `/', (or backward, `?')
through the buffer attempting to find a line that matches the RE.
The search will wrap to the top (or bottom) of the buffer if nec‐
essary. Search returns the line number that the match occurs on -
combined with the null command (see below) this causes the line to
be printed. Current is the matching line.
The null command is equivalent to asking for the line current+1 to
be printed according to the p command. This is a useful command to
quickly print the next couple of lines. If more than a couple of
lines are needed the z command (see above) is much better to use.
Current is the last line printed.
If an interrupt signal (SIGINT) is sent, ed prints `?' and returns to
BSD command pairs (pp, ll, etc.) are permitted. Additionally any single
print command may follow any of the non-I/O commands (I/O commands: e,
E, f, r, w, W, wq, and !). This will cause the current line to be
printed in the specified manner after the command has completed.
Previous limitations on the number of characters per line and per com‐
mand list have been lifted; there is now no maximum. File name and
path length is restricted to the maximum length that the current file
system supports. The undo command now restores marks to affected
lines. The temporary buffer method will vary dependent on the method
selected at compile. Two methods work with a temporary file (stdio and
db), while the third uses memory. The limit on the number of lines
depends on the amount of memory.
ed.hup: the buffer is written to this file in the current directory if
possible and in the HOME directory is not (if the signal SIGHUP
(hangup) is received).
B. W. Kernighan, A Tutorial Introduction to the ED Text Editor
B. W. Kernighan, Advanced editing on UNIX
ex(1), learn(1), regex(3), regex(7), sed(1), vi(1), POSIX 1003.2 (4.20)
`?name' for a file that is either inaccessible, does not exist, or is a
directory. `?' for all other errors unless the help messages have been
toggled on (with the H command) in which case a descriptive message
will be printed.
EOF is treated as a newline during input so that characters after the
last <newline> are included into the buffer; the message "<newline>
added at end of line" is printed.
Ed Returns an exit status of 0 on successful completion. A value >0 is
returned to indicate an ed error: 1 for a command line error, 2 for HUP
signal received, 4 for an ed command error; these error values will be
or'd together when appropriate.
Regular expressions are now described on regex(7). Ed follows basic
regular expressions (BRE's) as described on regex(7). BRE's, for the
most part, are the same as previous ed RE's. The changes to the RE's
are extensions for internationalization under POSIX 1003.2. Old scripts
with RE's should work without modification.
Regular expression logic is very tight. If you believe a command with a
regular expression in it has performed erroneously then a close reading
of regex(7) is likely required.
Address `0' is legal only for those commands which explicitly state
that it may be used; its use is illegal for all other commands.
The special form of substitute has been maintained for backward com‐
patability and should not be used in scripts if they are to portable.
Help messages may appear ambiguous to beginners - particularly when
BRE's form part of the command.
For backward compatability, when more addresses are provided than
required by a command the one or two addresses closest to the command
are used (depending on how may addresses the command accepts). Porta‐
ble scripts should not rely on this feature.
For backward compatibility the option `-' is equivalent to the `-s'
option at the startup of ed.
May 31, 1993 ED(1)