7 ways I use ed every day

We all have a favorite editor that we like to use. Some folks like Visual Studio Code or the open source version VSCodium because it’s a powerful editor packed with features. Others like the classic GNU Emacs because of the LISP-like extension language that makes it more flexible. And others prefer Vim because it’s light and runs everywhere, but doesn’t miss out on features. Or you could find a dozen other editors that people like to use.

And I like many of these editors. I don’t know how many editors I’ve used in my career, but it’s a lot. Every editor or IDE has a great use case, and I don’t stick to just one. I like Mousepad on Xfce to keep notes, Vim for editing small files, Geany for editing source code, Fed for writing programs on FreeDOS, and so on.

But there’s one editor I use every day that may surprise you: ed. The original Unix text editor, ed is actually a line editor, which means it operates on a line at a time. There’s no interface, everything runs on the terminal, without even a prompt. And yet I use it every day. Here are 7 ways that I find myself using ed every day to work with text files.

1. Editing files on the server

I manage several websites, and my hosting service provides a “shell” interface where I can connect via SSH to work directly on my files. This used to be a very responsive way to edit web pages or other files on the web server. Although I’ve noticed since AI bot activity has picked up, the web server has to work harder to respond to traffic across all of the websites hosted there. I don’t think I’ve seen the load average below 20 in the last six months.

The website is responsive, but obviously my interactive SSH sessions are not. Editing files using Vim just isn’t a pleasant experience when things are that slow.

Instead, if I only need to make a few quick edits, such as changing a color in a stylesheet file, I find it’s faster to just do it in ed. For example, if I decided that the “gold” color was too strong to use as a background color for highlighted text, I might use this ed session to change it to a lighter color. For this example, I might only have the one instance of “gold” in my stylesheet:

$ ed styles.css
2959
/gold
    background-color: gold;
s/gold/lightyellow/p
    background-color: lightyellow;
w
2966
q

2. Automating a process

I like using the command line, but I don’t like typing the same thing all of the time. If I know I’m going to do the same process a second or third time, I’ll usually find a way to automate it.

In one recent example, I needed to convert a bunch of Markdown files into PDF. The pandoc command will do that for me automatically, except that pandoc uses LaTeX to convert to PDF, and that was overkill for what I needed to do. Instead, I found it was faster to convert Markdown into some intermediate file format, like LibreOffice ODT or Word DOCX, and then use LibreOffice from the command line to process the file into PDF.

After a few experiments to make sure I had the right commands, I just needed to copy my commands into a Bash script. By using the ed editor, I could still see my previous commands in my shell window, which made it easy to create a script based on those commands.

$ ed mk-pdf.bash
mk-pdf.bash: No such file or directory
a
#!/bin/bash
pandoc --from markdown --to docx "$1" -o sample.docx
libreoffice --convert-to pdf sample.docx
.
w
106
q

$ bash mk-pdf.bash editor.md
convert sample.docx as a Writer document -> sample.pdf using filter : writer_pdf_Export

And when I ran the script, I realized the script should print a brief line when it is running pandoc, so I would know that was the step it was processing. So I made a quick edit with ed once again:

$ ed mk-pdf.bash
106
/pandoc
pandoc --from markdown --to docx "$1" -o sample.docx
i
echo 'converting with pandoc ..'
.
w
139
q

$ bash mk-pdf.bash editor.md
converting with pandoc ..
convert sample.docx as a Writer document -> sample.pdf using filter : writer_pdf_Export
Overwriting: sample.pdf

3. Writing a Makefile

Similar to automating a process with a Bash script is creating a Makefile to automate a build process. If I’m working on a large project with many source files, I’ll probably use an IDE like Geany to edit everything. But if it’s just a short program to do a specific thing, I might write that in Vim.

After I build the program and know it’s working, I usually create a Makefile to simplify the build process. If you haven’t used make before, you can use a Makefile to control how a project gets compiled, and what files are required to build the project. You can also add other steps to clean up after yourself, or to run a few tests.

And using ed is a great way to write a quick Makefile. Let’s say I just wrote a quick one-off program to do the Rot-13 “encryption” algorithm. Every time I build the program, I want to be sure to add the -Wall option with the C compiler, to report all warnings. I might also want to test the program to be sure it works correctly, so I’ll want to create a test target in the Makefile too. And finally, I’ll want to add a clean target to remove any temporary files.

That’s easy with a Makefile. It’s also trivial to write with ed:

$ ed Makefile
Makefile: No such file or directory
a
CC=/usr/bin/gcc
CFLAGS=-Wall
LDFLAGS=

RM=/bin/rm -f

.PHONY: all test clean

all: rot13

rot13: rot13.c
        $(CC) $(CFLAGS) -o rot13 rot13.c $(LDFLAGS)

test: rot13
        ./rot13 < t
        ./rot13 < t | ./rot13

clean:
        $(RM) *~ rot13
.
w
223
q

And with this Makefile, I can easily compile and test my program the same way every time without typing a bunch of commands:

$ make clean
/bin/rm -f *~ rot13

$ make test
/usr/bin/gcc -Wall -o rot13 rot13.c
./rot13 < t
Gur Ebg-13 "rapelcgvba" nytbevguz whfg ebgngrf
grkg ol 13 cbfvgvbaf. Sbe na nycunorg jvgu 26
yrggref, gung znxrf vg rnfl gb "qrpelcg" gur
zrffntr ol ehaavat Ebg-13 n frpbaq gvzr.
./rot13 < t | ./rot13
The Rot-13 "encryption" algorithm just rotates
text by 13 positions. For an alphabet with 26
letters, that makes it easy to "decrypt" the
message by running Rot-13 a second time.

4. Writing a test file

When I work on a project, I’ll go through several iterations to add some new feature, then test it to make sure everything works the way I want it to. I’ll often test it with files that I know work and other files that I think might not work to try to break it, so I can learn to catch those conditions before they cause a problem in the program.

You don’t need to run an instance of a big editor just to create a test file that’s a few lines long. Instead, I find it’s much faster to start a new file in ed and create my test file there.

$ ed t
t: No such file or directory
a
This is a test file.
        This line starts with spaces.
THIS LINE CONTAINS ALL UPPERCASE.
.
w
85
q

5. Writing a demo program

I’ll use an IDE to work on large projects, or a programmer’s editor to work on big but not too-large projects, and Vim for small things. But for those cases where I just need to write a program that’s a few lines long, I’ll use ed.

A few weeks ago, I was working on an article to explain some features of the classic FORTRAN 77 programming language. I don’t know that FORTRAN 77 is used much anymore, but it was the programming language we used during my physics undergraduate days to write data analysis or numerical simulation programs, so it’s something that’s stuck with me.

And because what’s old is new again, retro programming means that people want to read about FORTRAN 77. So that’s why I found myself needing to write a few short programs in FORTRAN 77 to explain how a DO loop worked, or how the ASSIGN statement could be used with GOTO to create a primitive kind of subroutine. These are not big programs. I found it was easier to just type out a few lines in ed, compile it, and run it—all from the command line.

$ ed do.f
do.f: No such file or directory
a
      PROGRAM LOOP
      DO 10 I=1,10,1
10    PRINT *, I
      END
.
w
67
q

$ f77 -o do do.f

$ ./do
           1
           2
           3
           4
           5
           6
           7
           8
           9
          10

6. Fixing typos

I write the first draft of most of my articles in Markdown, because it lets me focus on the content of what I need to say without getting distracted by the formatting to make it look nice. And part of that focus is not worrying too much about typos. If there’s a red squiggle, I’ll ignore it as I’m writing and fix it later.

Since I’m writing in Markdown, which is just plain text with some minimal markup for basic formatting, I use a command line tool called typo to identify misspelled words. This is actually a script that I wrote several years ago, and it mimics a similar command from the original Unix. The script outputs a list of possibly misspelled words, and it’s up to me to edit the file to fix the errors.

If I use Vim or some other full-screen terminal-mode editor to edit the file, I won’t be able to see the output from typo anymore. So no matter what editor I might have used to write the original document, I usually turn to ed to fix the typos.

Here’s a sample session where I ran typo to find possibly misspelled words in an early draft of this article. Most of the words that typo listed were not actually misspelled, except the word eidtor, which I needed to fix manually in ed:

$ typo editor.md
docx
eidtor
geany
mousepad
ssh
stylesheet
vscodium
xfce

$ ed editor.md
8571
/eidtor
| `q`     | Quit the eidtor. If **ed** prints a question mark, that may mean you haven't saved the file. |
s/eidtor/editor/p
| `q`     | Quit the editor. If **ed** prints a question mark, that may mean you haven't saved the file. |
w
8571
q

7. Just for fun

In days long ago, technical writers used tools like nroff to create documents including reports, letters, and memos. I first used nroff when I was an undergraduate student; it was a great way to work on class papers from anywhere on campus, just by logging into one of the VT220 terminals available in most of the academic buildings at the time.

And sometimes, I like to write documents with nroff just for fun. Yes, even in 2025.

When I’m writing just for me, I don’t need a big editor, and I don’t need conditional formatting to highlight keywords. The ed editor will do the job just fine. So I’ll often write a sample document, formatted for the -ms macros, using ed.

$ ed doc.ms
doc.ms: No such file or directory
a
.TL
Document Title
.AU
Jim Hall
.AI
Author's Institution
.AB
This is an abstract. Use this to provide a brief summary of the
document and highlight important points. Many of my undergraduate
lab reports required an abstract.
.AE
.NH 1
Introduction
.PP
Here's a sample document written in nroff.
I used to write class papers in nroff when I was an undergraduate,
because I could connect to the Unix systems from anywhere on campus
that had a VT220 terminal. And I could print my documents just as
easily using the dot matrix printer in the computer lab.
.
w
553
q

Try it for yourself

The ed editor may be a simple line editor, but it still does the job of editing text. As a line editor, ed operates one line at a time, using commands to enter edit mode and manipulate files.

If you want to get started writing with ed, here are a few key commands to know:

CommandWhat it does
aAppend new text starting after the current line. This is also how you start writing in a new file.
iInsert new text before the current line.
cChange (replace) the current line.
.Type . on a line by itself to stop entering lines.
/text or ?textSearch forwards (or backwards) for text, using regular expressions. This also sets the new current line to use with the a or i or c commands.
s/old/new/Replace text, from old to new. You can change every line* by using % at the start.
wWrite the file (save it).
qQuit the editor. If ed prints a question mark, that may mean you haven’t saved the file.

This article is adapted from How I use the ed editor by Jim Hall, and is republished with the author’s permission.

Leave a Reply