I am sure everyone has tried to use ed at least once. And I’m also sure some people have read Ed, the standard text editor. Its cryptic error messages (just ? actually) and the lack of any user interface probably turns most people away from it. I have to admit, I tried to use it before without any success. I spent probably 15 seconds in it before kill -9‘ing the process. But the truth is, ed is actually really easy to use after doing about 3 minutes of reading.

It started with me reading a comment on reddit which mentioned ed. That comment, along with the memory of Ed, the standard text editor convinced me to give it an actual try this time. I googled ed tutorial and pretty soon I was able to use ed for basic editing. In fact, this post is (hopefully) written entirely in ed.

Before we begin, let me show you how to quit ed. You probably noticed that exit, quit and Ctrl+C don’t work. That is because all commands in ed are single characters, since it was designed in a time where every byte mattered. The command for quitting is q, so typing q and hitting Enter should get you out of the editor. With that out of the way, let’s get to the important stuff.

Picking a prompt

The screen that comes up when you launch ed isn’t actually a text area, it is a Command Prompt. But this is hard to tell because by default, ed doesn’t have any indicators for being in the command mode. The first thing we should do is to pick a prompt for ourselves. I use 🔥> but you can pick any string you want. It can contain Unicode emojis if you want, or it can just be a simple :.

We can set the prompt from a command line argument like ed -p"🔥 > ". You’ll want to make this the default setting. Ed doesn’t have a config file, but you can add this as an alias to your .bashrc. Here’s the relevant line from my .bashrc as an example: alias ed='ed -p"🔥 > "'. From now on whenever you open ed, you will be met with a familiar prompt.

$ ed
🔥>

Writing FizzBuzz

When we open ed, it creates an empty buffer for us. In order to start editing, we can use the a command. It stands for append and it will let us input some lines into our file. After we are done, we can write a single . on a line to get back to command mode. Let’s write some example code.

🔥> a
#!/usr/bin/env phyton3

for i in range(1, 101):
    if i % 15 == 0:
        print("FizzBuzz")
    elif i % 3 == 0:
        print("Fizz")
    elif i % 5 == 0:
        print("Buzz")
    else:
        print(i)
.
🔥>

Printing the buffer

You can print the current line with the p command. This command takes a range so you can use 4p to print to fourth line. I’ll show you 3 ways to print lines 3, 4 and 5.

🔥> 3p
for i in range(1, 101):
🔥> 4p
    if i % 15 == 0:
🔥> 5p
        print("FizzBuzz")
🔥>

Most commands in ed take a range, so you can combine them like this.

🔥> 3,5p
for i in range(1, 101):
    if i % 15 == 0:
        print("FizzBuzz")
🔥>

You can also use n instead of p to print with line numbers.

🔥> 3,5n
3    for i in range(1, 101):
4        if i % 15 == 0:
5            print("FizzBuzz")

You can use “,” as a range, this means you want the command to work on the whole file. For example; running ,n will print the whole file with line numbers, which should make editing a lot easier.

Saving the file

The buffer can be saved to a file using the w (write) command. It takes an argument, the file name, but it can be skipped if ed knows the file name. If you ran ed with a command line argument or if you used the w command in the session, ed should remember the name for you. This command will print the number of bytes written.

🔥> w
206

Reading a file

Just like the write command, you can use r to read a file to the current buffer or the e command to replace the current buffer with a file. All those commands will result in ed reporting the number of bytes read.

🔥> r /etc/hosts
865

You can read the output of a shell command by prefixing it with !, just like in Vim.

🔥> r !ls
65

Making edits to the file

There are multiple ways to edit a line in ed. Let’s use those to make the code print Three, Five and Fifteen instead of Fizz, Buzz and FizzBuzz.

1. Rewriting the line:

The first way we can change a line is to rewrite the whole line. For this we will use the c (change) command. To fix the first line, we can do.

🔥> 1
#!/usr/bin/env phyton3
🔥> c
#!/usr/bin/env python3
.
🔥>

2. Substitution

So we want to change Fizz, Buzz and FizzBuzz to Three, Five and Fifteen. If we don’t want to rewrite those long lines, we can use the s (substitute) command.

🔥> 5
        print("FizzBuzz")
🔥> s/FizzBuzz/Fifteen/
🔥> p
        print("Fifteen")
🔥>

We can also combine those 3 commands like this.

🔥> 5s/FizzBuzz/Fifteen/p
        print("Fifteen")
🔥> 7s/Fizz/Three/p
        print("Three")
🔥> 9s/Buzz/Fize/p
        print("Five")
🔥>

Deleting a line

The d (delete) command can be used to delete a line. This command also takes a range.

  • 🔥> d
  • 🔥> 4d
  • 🔥> 3,5d

Selecting based on Regular Expressions

You can use the g command to select lines based on a regex. For example, to delete all lines containing TODO, we can do.

🔥> g/TODO/d

Instead of the deleting with d, we can print the lines with p. Let’s print all lines matching the regular expression re.

🔥> g/re/p

Looks oddly like grep doesn’t it?

Searching

You can move to the next line matching a regex with /, the same command as Vim.

🔥> /range
for i in range(1, 101):

A search in the backwards direction can be performed with the ? command.

🔥> ?python
#!/usr/bin/env python3

Thanks for reading this post, now you should know how to write and edit simple files in ed. As a challenge, try writing a C program in ed that reads a line and prints “True” if it’s a palindrome.

You can also see the ed manual for more information.