ed
is a “line editor” and not a text editor. It’s a distant ancestor to vi
, so some commands are may seem familiar.
These are my notes on basic usage, which should be enough to get you started. You’re probably not going to want to use this to write software, but I’ve used it in the past inside scripts for when file modifications are slightly less trivial than append / delete.
Expressions
These are some basic definitions that’re used in command definitions in the next section.
-
line - select a single line
- Examples:
- Simple line selection:
1
- select line 1.$
- select the last line of the file.
- Basic add/subtract is also supported:
$-2
- select two lines above the last line.1+2
- selects the third line.$-
- selects the second to last line file. Equal to$-1
.
- Simple line selection:
- Examples:
-
range - this is combined with multiple other commands. Running a range standalone selects the last line. Any two line expressions can be combined here.
- Examples:
1,5
- selects line 5.1,$
- selects last line of the file.1,$-
- selects all but the last line of the file
- Examples:
-
regex - matches lines containing a regular expression
- Examples:
g/foo/
- selects lines containing the string “foo”
- Examples:
-
inverted regex - matches lines not containing a regular expression
- Examples:
v/foo/
- selects lines not containing the string “foo”
- Examples:
-
addr - in the below commands, “addr” can mean either:
- a line
- a range
- a regular expression
Commands
For most of these commands, the preceding address is optional, and just uses the current position (which can be set by entering a line / range).
Printing
There are two commands for printing a line / range of lines, n
and p
. They accept the similar address parameter like most other commands:
-
<addr?> n
- prints with line numbers- Examples:
n
- prints current line5n
- selects line 5 and prints it.1,5n
- prints the first 5 lines1,$n
- print entire documentg/foo/n
- prints lines containing “foo”v/foo/n
- prints lines not containing “foo”
- Examples:
-
<addr?> p
- prints selected lines- Examples:
p
- prints current line1,5p
- prints the first 5 lines5p
- selects line 5 and prints it.1,$p
- print entire document
- Examples:
Editing
-
<range>? j
- joins selected lines- Examples:
1,5j
- joins the first 5 lines
- Examples:
-
<addr?> d
- deletes selected lines- Examples:
1,5d
- delete the first 5 linesd
- delete current line5d
- deletes line 5 and prints it.g/hi/d
- delete all lines containing “hi”
- Examples:
-
<line?> a
- append after selected line- Examples:
10a
- add lines after line 10. This enters insert mode, and you must terminate your entry with a new line containing a single ”.”
- Examples:
-
<line?> i
- insert before selected line- Examples:
10i
- add lines before line 10. This enters insert mode, and you must terminate your entry with a new line containing a single ”.”
- Examples:
-
<addr?> m <line>
- move section from one part to another. Appends directly after the referenced line.- Examples:
4m1
move line 4 to after line 1.4,5m1
move lines 4-5 to after line 1.
- Examples:
-
<addr?> t <line>
- copy section from one part to another. Appends directly after the referenced line.- Examples:
4t1
copy line 4 to after line 1.4,5t1
copy lines 4-5 to after line 1.
- Examples:
-
<addr?> c
- replace line(s) with one or more lines.- Examples:
1c
Replace line one. This enters insert mode, and you must terminate your entry with a new line containing a single ”.”1,5c
This replaces lines 1-5. This enters insert mode, and you must terminate your entry with a new line containing a single ”.”
- Examples:
Search & Replace
-
/regex
search- Cycles through all matches when pressing enter.
- The current match may be utilized during each iteration
- Examples
/foo
- loop through lines containing the regex match for “foo”
-
<addr?> s/oldstr/newstr
- single regex replace- Replace first occurrence of “oldstr” with “newstr” in the specified lines
- Examples
1s/foo/bar
- replaces first occurrence of “foo” -> “bar” in line 1.1,$s/foo/bar
- replaces first occurrence of “foo” -> “bar” in the entire file
-
<addr?> s/oldstr/newstr/g
- global regex replace- Replace all occurrences of “oldstr” with “newstr” in the specified lines
- Examples:
1s/foo/bar/g
- replaces all occurrences of “foo” -> “bar” in line 1.1,$s/foo/bar/g
- replaces all occurrences of “foo” -> “bar” in the entire file
File Management
-
f <filename>
- changes current filename- Examples:
f example.txt
- changes editing name to example.txt. Note that this does not change the current file, it just affects the next write.
- Examples:
-
<addr?> r <filename?>
- read lines into buffer from file. Ifaddr
is not specified, current position is used.- Examples:
r ./example.txt
- loads “example.txt”r !ls -la
- loads output of command ls-la
- Examples:
-
<addr?> w <filename?>
- write current file contents (replace)- uses all the lines if none are specified
- uses current filename if not specified
-
<addr?> W <filename?>
- append current file contents (append)- uses all the lines if none are specified
- uses current filename if not specified
-
q
- edit current contents
More info
- There’s a bunch more commands I haven’t mentioned, you should checkout the manpage (for GNU ed) here - https://www.gnu.org/software/ed/manual/ed_manual.html
Example Usage using a here document
This example appends a header to the start of a file. Here, we’re appending after line 0, which is the start of the file. I’ve used this to programatically add information to an entire directory of files, using it in combination with a for loop
ed -s "example_file.c" << EOF
0a
/*
* EXAMPLE FILE HEADER
*
* Potentially include license and copyright info here.
*/
.
w
EOF