The ed(1) utility is a powerful, line-oriented editor.
Although ex(1) and vi(1) have gained popularity,
ed(1) still maintains advantages over them. Some of the most
notable advantages of ed(1) are: the W command,
described later in this topic and which is not part of ex(1)
or vi(1); the smaller executable size (you can often begin
editing before the others finish loading); and the better response
when editing from slow terminals or across low-baud data lines. The
ed(1) utility continues to be used by many system
utilities.
When a filename is present, ed(1) starts by
simulating an e command (described later in this topic). If
no file name is present ed(1) starts with an empty
buffer.
Set the prompt to prompt-string. The default prompt is
*. (See also the P command.)
-s
Suppress the printing of explanatory output from the commands
e, E, r, w, W and wq.
This option should be used with a script.
-v
Display a message that describes which of BSD or POSIX mode
ed(1) has been set. This is useful for determining the
behavior described in the following section.
The ed(1) utility performs all changes to a copy of the
file that 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. Commands that accept zero addresses regard
the presence of any address as an error.
The ed(1) utility works in two modes: command, and input.
The two modes are exclusive of each other. While in command mode,
ed(1) accepts commands that display, modify, or give
information about the buffer. While in input mode ed(1)
accepts lines of text to be added to the buffer.
Addressing in ed(1) specifies one or more lines contained
in the buffer. For commands that expect at least one address, if
none are given, default addresses will be used. To use addresses in
ed(1), it is important to know that, during the execution of
most ed(1) commands, a current line (current)
exists. Current is usually the location in the buffer that
the last command issued affected, although some commands do not
affect current. Each command description (discussed later)
describes its affects on current.
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
following:
A positive decimal integer (such as 123), indicating a line
number in the buffer. Line number 1 is the first line in the
buffer.
The period (.), indicating the current line
(current).
The dollar sign ($), which indicates the last line in
the buffer.
A regular expression (RE) enclosed with forward slashes
(/) as delimiters (that is, /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
forward slash from being a delimiter. The search will wrap from the
bottom of the buffer to the top of the buffer if necessary. The
ed(1) utility REs are, outside of this document, now
referred to as basic regular expressions. Basic regular
expressions (BREs) are those that have traditionally worked in
ed(1). BREs are, for the most part, the same as the old
REs—the name has changed and the expressions have been extended to
meet POSIX 1003.2 specifications. (See the search command for more
details.)
An RE enclosed with question marks (?) as delimiters
(that is, ?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 question mark
from being a delimiter. The search will wrap from the top of the
buffer to the bottom of the buffer if necessary. (See the search
command for more details.)
A line previously marked by the k command (described
later). 'x addresses the line marked by the single
lowercase letter 'x' (from the portable character set in the
range a-z).
An address of the form 1-6, followed by a '+', followed by an
integer number, n. This specifies that the line to be
addressed is n lines after the address of the form 1-6. If
the address starts with a '+', by default, the addressed line is
taken with respect to current (equivalent to '.'; form 2).
If no integer number is given, 1 is added to the address. If more
than one '+' is given in a sequence, with no integer number
following, 1 is added to the address for each '+'. Therefore, +++
is equivalent to +3, but +++1 is equivalent to +1.
An address of the form 1-6, followed by a '-', followed by an
integer number, n. This specifies that the line to be
addressed is n lines before the address of the form 1-6. If
the address starts with a '-', by default the addressed line is
taken with respect to current ('.'; form 1). If no integer
number is given, 1 is subtracted from the address. Hence, if more
than one '-' is given in a sequence, with no integer number
following, 1 is subtracted from the address for each '-'.
Therefore, --- is equivalent to -3, but ---1 is equivalent to -1.
For backward compatibility '^' is the equivalent to '-'.
A comma (,) can 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.
A semicolon (;) can 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
buffer than the second address to be legal.
Addresses of the forms 7 and 8 cannot be followed by addresses
of forms 2-6; doing so 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(1) 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 in the following list. These suffixes may be
combined in any order.
(.)a text .
Append text after the addressed line. A '.' in the first
column, followed immediately by a newline, places ed(1) 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).
(.,.)c text .
Change text on one or more addressed lines. The addressed lines
are deleted before ed(1) is placed in input mode. A '.' in
the first column, followed immediately by a newline, places
ed(1) 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).
(.,.)d
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.
e [filename]
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(1) will issue a
warning ('?'); a second 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 filename is lead by a '!',
it will 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 [filename]
E works the same as e, except that if the buffer
has been modified, no warning is issued.
f [filename]
Print the remembered filename. If filename is
specified, the remembered filename is set to
filename. If filename is lead by !, it is
interpreted as a shell command to be executed, from which the
standard output is be used as the new remembered file name.
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. In
the command list, one command usually occupies a line. To have
multiple commands in the command list, you must 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(1) into
input mode, the newlines of the entered text must 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 information about the behavior of each
ed(1) command within a command list, refer to the
information on the individual command, particularly s and
!. The commands g, G, v, V, and
! are permitted in the command list, but should be used with
caution. The command list defaults to p if left empty (that
is, g/RE/p). For the regular expression, the delimiters can be any
characters except space and newline; delimiters within a regular
expression can be escaped with a backslash preceding it.
(1,$)G/regular expression/
The interactive global command works very much like g.
The first step is to mark every line that 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
buffer. '%' by itself executes the last non-null command. A return
by itself acts as a null command. Current is set to the last
line affected by the last successful command input. If no match or
an input command error occurs, current is set to the last
line searched by G. G can be prematurely ended by
(SIGINT). For information about the behavior of each ed(1)
command within a command list, refer to the information on the
individual command, particularly s and !.
h
The help command displays a message explaining the most recent
command error (indicated by '?'). Current is unchanged.
H
This toggles on or off the automatic display of messages
explaining the most recent command error in place of '?'.
Current is unchanged.
(.)i text .
The insert command places ed(1) in input mode, and
places the text before the addressed line. Line 0 is invalid for
this command. A period (.) in the first column, followed
immediately by a return, places ed(1) back in command
mode.The '.' is not included in the text. Current is the
last line inserted. If no text is inserted, current is the
addressed line.
(.,.+1)j
The join command joins the addressed lines together to make one
line. If no addresses are specified, the current and
current lines are joined. If only one address is given, no
join is performed. Current is unchanged.
( . )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.
(.,.)l
The list command prints the addressed lines in an unambiguous
way: non-graphic characters are printed in three-digit octal,
preceded by a backslash (\) unless they are one of the
following, in which case they will be printed as indicated in the
parentheses: 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 !).
(.,.)ma
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.
(.,.)n
The number command prints the addressed lines preceding the
text with the line number. The n command can 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.
(.,.)p
The print command prints the addressed lines. The p
command can 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.
(.,.)P
The prompt is toggled on or off. Current is unchanged.
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(1) to exit. If the entire
buffer (1,$) has not been written since the last modification,
ed(1) issues a warning once ('?'); a second issuing of the
command will be obeyed regardless.
Q
Q works the same as q, unless the buffer has been
modified, in which case, no warning is issued.
($)r [filename]
The read command reads in the file filename after the
addressed line. If no filename is specified, the
remembered filename is used. Address 0 is valid for this
command. If read is successful, the number of characters read is
printed (unless the -s option is specified). If
filename is lead by exclamation mark (!), it will 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 (described later). If no flags
appear, by default, only the first occurrence 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 or
replacement.
An ampersand, (&) appearing in the replacement will
equal the string matching the RE. The special meaning of
& can be suppressed by leading it with a '\'. When '%'
is the only replacement character in replacement, the most
recent replacement is used. The special meaning of '%' can be
suppressed 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 back referencing). S can be used to break lines by
including a newline in replacement, preceded by a '\' to
escape it. Replacement can continue on the next line and can
include another escaped newline.
The following extension should not be included in portable
scripts. When splitting 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 backslashes; 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 continues). (N.B. Other ed(1)
implementations do not allow line splitting within the global
commands.)
The flags may be any combination of:
count
In each addressed line, replace the instance of the matching
occurrence specified by count.
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 instance of matching
specified by countto 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 can 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 where the last replacement occurred
(POSIX).
(.,.)ta
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.
(.,.)u
The undo command nullifies the most recent buffer-modifying
command. The undo command reverses the following buffer-modifying
commands: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 reverses 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 nonmatching 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 nonmatching command is the same as
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
filename. If no filename is specified, the
remembered filename is used. If no addresses are specified,
the whole buffer is written. If the command is successful, the
number of characters written is printed (unless the -s
option is specified). If filename is lead by !, it
will be interpreted as a shell command to be executed which will
accept on its standard input the section of the buffer specified
for writing. Current is unchanged.
(1, $)W [filename]
W functions like the w command does, except that
the addressed contents of the buffer are appended to
filename (or the remembered filename if
filename is not specified). If filename is lead by
!, W will act exactly as the w command.
Current is unchanged.
(1, $)wq [filename]
wq works just as the w command does, except that,
in addition, ed(1) exits immediately after the write is
complete. Current is unchanged.
(1,$)Wq [filename]
Wq works as the W command does, except that, in
addition, ed(1) exits immediately after the appended write
is complete. Current is unchanged.
(.+1)z
(.+1)zn
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
provided (in the forms 1-8 above), the line number for that line
will be printed. Current is unchanged.
!shell command
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 '!' immediately after ! repeats the last shell
command. An unescaped '%' represents the remembered file name.
Commands to sh(1) can have several lines by escaping the
newline with a '\' immediately before it. The line-continuation
character for sh(1), backslash (\) can be included on
a line provided that it is escaped by a backslash (\)
immediately before, so that ed(1) passes it literally to
sh(1): '\\'. It is implicit that, for the command
line that the sh(1) line-continuation character is on, the
newline will be escaped (such as '\\\newline'). This behavior can
be used within global command lists. However, an additional
backslash (\) must be added so that the ! command
continuator is passed to !. It must occur immediately before
the global command's continuator. Therefore, the !
command-continuation sequence in a global command list will appear
as '\\\' (explanation as with s). The line-continuation
character for sh(1) needs no additional escaping (since it
is not dependent on newline being adjacent). Hence, the sequence in
a global command list with a line continuation will appear as
'\\\\\newline'. Current is unchanged.
/regular expression/ ?regular expression?
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
necessary. Search returns the line number on which the match
occurs, combined with the null command. This causes the line to be
printed. Current is the matching line.
(.+1,.+1)newline
The null command is equivalent to asking for the line
current to be printed according to the p command.
This command can be used to print the next few lines quickly. If
more than a few lines are needed, however, it is better to use the
z command described previously. Current is the last
line printed.
If an interrupt signal (SIGINT) is sent, ed(1) prints '?'
and returns to command mode.
BSD command pairs are permitted. Additionally, any single-print
command can 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 command list have been lifted; there is now no maximum. File
name and path length are 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,
depending 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).
'?name' for a file that is 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.
The ed(1) utility returns an exit status of 0 on
successful completion. A value >0 is returned to indicate an
ed(1) error: 1 for a command line error, 2 for HUP signal
received, 4 for an ed(1) command error; these error values
will be combined using a bitwise OR when appropriate.