I.T. Consulting
Tutorials
Sysadmin
How RAID Works What's a RAID? Hardware vs Software RAID Striping and Mirroring RAID 2 and 3 RAID 4 and 5 Conclusion
Software RAID on Linux RAID: Quick Recap Software Tools Creating & Using an Array Monitoring an Array Removing & Re-Assembling an Array The mdadm.conf File Deleting an Array Summary & Cheat-Sheet
Network Security
Squid Proxy Server Basic Configuration Controlling Traffic Blocking Access Monitoring Traffic
SSH: Secure Shell Overview Using SSH Encryption Authentication Keys Configuring SSH Advanced Tricks
Implementing HTTPS What Is HTTPS? Setting Up The Server
Linux Skills
The ed Line Editor First Things First Navigating Entering Text Changing Text Line Maneuvers Text Searches Using ed in Real Life Summary
Regular Expressions Text Patterns Extended Expressions
The vi Editor Introduction Operating Modes Navigation Editing Summary
Intermediate vi Power Editing Cut-and-Paste Modifying Text Searches Tips & Tricks The vi Prompt Indenting
Miscellaneous
Creating an eBook Introduction Create an ePub Create a MOBI Create a PDF

The ed Text Editor

First Things First

Trust me on this: In order to understand what ed is all about, it's necessary to explain where it came from. That means a quick history lesson.

Let's go back in time several decades ago, back to the sixties. Before there was vi, there was a line editor named ed, which was basically a programming language for text.

Back then, programmers were using hard-copy terminals, which were essentially a printer with a keyboard attached. There was no screen and therefore no cursor to move around.

Now, imagine you had to edit text on a hard-copy (paper) terminal. How would that work? Well, you would have to enter commands to instruct the program to either display a line from the file, or make changes to it, or add new text to the file, etc.

This is how ed worked. If you wanted to enter text into a file, for instance, you would invoke ed with the desired filename, then enter the command "i" (for "insert") on a line by itself and that would tell ed that whatever text you would type afterwards was meant to go into the file.

When you were finished entering the desired text, you would type a single dot on a line by itself, and that would tell ed to return to command mode, where other letters would mean something to the editor, such as "w" to write the file out to the disk drive, and "q" to quit.

If you know vi, all this will sound awfully familiar. That's because vi is acutally an outgrowth of ed.

Here's what happened: as video terminals became more and more prevalent in the workplace, a programmer named Bill Joy added extra functionality to the original ed program and renamed it ex to reflect its expanded command set. One of these new commands was "visual," or "vi" for short, which told the editor it was being used on a CRT terminal and not on a hard-copy paper terminal. When this option was invoked, the editor would display 24 lines of text on the screen and enable cursor motion.

This feature was so commonly used that the program was tweaked so that if it was invoked under the name vi instead of ex, it would automatically come up in visual mode. In more technical terms, the commands vi and ex are actually both links to the same program; the user interface is either line-by-line or full-screen depending on which name is used to invoke the program.

Why learn ed?

This little bit of history might be interesting if you're into trivia, but why would anyone need to use ed today?

The main reason is that ed and its cousins ex, vi and sed are capable of sophisticated pattern-matching operations which are incredibly useful, both in manual text editing and in automated operations through shell scripts.

More specifically, if you are currently using vi to edit code, you will definitely want to learn ed because you can apply all the sophisticated text-matching operations available in ed directly from vi.

In addition, the pattern-matching expressions used by ed are also used in sed, awk grep, tr and expr, as well as other less mainstream utilities. So, if you are planning to write non-trivial shell scripts, you will be wise to spend some time learning the basic ed command set; it will serve you well for years on end.

Invoking the ed editor

Although ed was originally designed for hard-copy terminals, there is no reason you can't use it on a standard computer screen as well.

Normally, you will invoke ed with the name of the file to edit as argument. However, if you don't specify a filename, you can still use ed normally but you will need to specify a filename when saving your text.

Let's assume we are about to edit the following file, named laws:

The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.

We can invoke ed in this manner:

$ ed laws
188
_

The number 188 represents the number of bytes read into the editor, which is the size of the file. Note that there is no prompt and that the file is not displayed; only a blinking cursor is present, waiting for instructions.

If you invoke the editor without a filename, no number is shown, indicating no data was read:

$ ed
_

Exiting ed

From this point on, ed expects you to issue programming instructions to display or edit the text, or perform other tasks such as text searches. Although we have not yet done any work in this file, the first thing you should learn about any program is how to get out of it. The command to exit ed is q for "quit". Simply enter q on a line by itself, then press ENTER to exit ed, as in this example:

$ ed laws
188
q
$ _

NOTE: In our examples, bold characters denote text that you enter, while the normal font shows what the program would generate. Note also that all ed instructions are case-sensitive; a Q is not the same as q.

Typically, during an editing session, you will have made changes to the file and you will need to save these changes before exiting. If you try to exit (by entering q on a line by itself) without first saving your changes, ed will display a question mark as a warning; if you enter q a second time, ed will take it as an instruction to quit unconditionally, without saving:

$ ed laws
188

     (...a number of editing changes here...)

q
?    (warning that we have not saved our work...)
q    (Insist by repeating the command)
$ _

Alternately, entering a capital Q means "quit unconditionally"; ed will quit immediately, even if you have not saved your changes:

$ ed laws
188

     (...a number of editing changes here...)

Q
$ _

 

 

Navigating in ed

Command-driven interface

ed is a command-driven editing tool. To do anything in ed, you must give it instructions of the form:

<number><command>

where <number> is either a line number or a range of lines, and <command> is an editing instruction. Let's illustrate this with two of the most common editing instructions:

p "print" (i.e. display) the line(s) specified by <number>
d delete the line(s) specified by <number>

For instance, the command 3p would display line number #3 while 3d would delete that line.

Note that you will encounter the term "print" instead of "display" in a lot of older utilities such as ed, awk and sed due to the widespread use of hard-copy terminals when these utilities were created. It's too late to change things, so we might as well accept the antiquated terms graciously.

Line Ranges

Line ranges can be specified by separating the starting and ending lines with a comma. For instance, the command 1,3p displays ("prints") the first three lines; the command 2,5d deletes lines 2 to 5 inclusive.

The special character "$" stands for "last line", whatever number that is. For instance, in our previous example, we could display the entire file like this:

$ ed laws
188
1,$p
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
_

To delete the second law in the list (line number 3), you could issue the command 3d as in this example:

$ ed laws
188
1,$p
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
3d
1,$p
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useless, it will have to be documented.
_

The Current Line

The editor "remembers" the last line on which any work was done as the current line. When no line number is specified, the current line is assumed. For instance, the command p without a line number will display the current line. Similarly, the command d by itself will delete the current line.

At the beginning of a session, the current line is the last line of the file because reading this line was the last thing ed did as it loaded the file in memory.

Moving Within a File

You can make the current line any line of your choice by simply entering the line number without an editing instruction.

For instance, entering 2 will make line #2 the current line and will also display it:

$ ed laws
188
1,$p
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
2      (make line #2 the current line) 
Any given program, when running, is obsolete.
_

To move up or down the file, simply enter the minus sign to go back one line, or press ENTER to go forward one line:

$ ed laws
188
2        (make line #2 the current line) 
Any given program, when running, is obsolete.
        (go back one line) 
The laws of computer programming:
<Enter>        (next line...) 
Any given program, when running, is obsolete.
<Enter>        (next line...) 
If a program is useful, it will have to be changed.
<Enter>        (next line...) 
If a program is useless, it will have to be documented.
_

Using Relative Line Numbers

A single dot represents the current line number and may be used in line ranges. For instance, the expression 1,. means from line 1 to the current line; the expression .,$ means from the current line to the end of the file:

$ ed laws
188
2        (make line #2 the current line) 
Any given program, when running, is obsolete.
1,.p
The laws of computer programming:
Any given program, when running, is obsolete.
.,$p
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
_

To find out which line number is the current line, simply use ".=" as in this example:

$ ed laws
188
.=        (what is the current line number?) 
4
_

Note that the initial line number right after invoking ed is the last line of the file since ed has just read the entire file into its memory buffer. Note also that using the equal sign by itself (i.e. not preceded by a dot) displays the total number of lines in the file.

A minus or plus sign may be used to specify relative ranges. For instance, +3 means the third line below; -1 means the line above to the current line.

Relative numbers may also be used in ranges. For instance, the range .,+2 means "from here to 2 lines below," for a total of 3 lines as shown here:

$ ed laws
188
2 &nsbp;      (make line #2 the current line) 
Any given program, when running, is obsolete.
.,+2p
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
_

If you specify an invalid range, such as line #5 in a four-line file, ed replies with a simple question mark, indicating an error occurred (the current line remains unchanged):

 

 

Entering Text

Insert and Append

There are two commands to enter new text in a file:

i Insert new text (before the current line)
a Append new text (after the current line)

After you have entered either of the above commands, whatever you type at the keyboard will go into the file at the current line position. Remember that you have to press ENTER at the end of each line; the editor will not truncate long lines the way word processors do.

To end text entry, simply enter a period as the first character of a line. This method was chosen because a period on a line by itself is very unlikely text. However, if you need to insert a single period on a line by itself in your text, simply precede the period with a backslash to "escape" this character (the backslash is used quite universally in Unix utilities as an escape character).

In the following example, we are using the i instruction to insert a blank line just before line 2, then the a instruction to add a few lines to the text:

$ ed laws
188
1,$p        (Display the whole file) 
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
2i        (Insert before line 2...) 
Any given program will expand to fill all available memory.
.      (After entering the above text, enter a dot to terminate) 
1,$p        (Display the file again to see the result) 
The laws of computer programming:
Any given program will expand to fill all available memory.
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
$a        (Append text after last line) 

Anonymous
.        (This dot indicates the end of text input) 
1,$p
The laws of computer programming:
Any given program will expand to fill all available memory.
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.

Anonymous
_

Saving Your File

If you have made changes to the file and wish to save these changes, you can do so with the w instruction (for "write"). Your file will be saved under the name you used when you invoked ed.

$ ed laws
188
$a        (Making a change to the file) 

Anonymous
.
w        (Save the file) 
208        (ed displays the number of bytes saved) 
q        (Exit the editor) 
$ _        (Back to the shell prompt) 

If you invoked ed without an argument, or if you would like to save your file under a different name, simply specify the desired filename as an argument to the w instruction, as in this example:

$ ed laws
188
w testfile        (Save file under new name) 
188
q        (Exit the editor) 
$ _

As with most ed instructions, you can specify a line number or a range of lines to save only the desired amount of text. This is how you would cut out a block of text and save it as a separate file. For instance, to save lines 2 and 3 only as a new file block, use:

$ ed laws
188
2,3w txt_block        (Save only two lines to file "txt_block") 
98        (Only 98 bytes were saved) 
_

 

 

Changing Text

The Change Command

We have already seen how to delete lines with the d instruction. There is also a c instruction to change lines. This is equivalent to deleting the desired lines, then using i or a to enter new text, except that the whole thing is done using a single command.

For example, to change lines 2 and 3 to anything else, simply enter the command 2,3c. This will effectively delete lines 2 and 3, then put you in insert mode. Whatever you enter from that point on will be placed where lines 2 and 3 used to be, effectively changing the old text to the new text.

Although you are replacing two lines of text in this particular case, you don't necessarily have to enter two new lines of text; any amount of text you enter will replace these two lines, be it a single word or an entire chapter.

When finished, simply enter a single dot on a line by itself to return to command mode, like this:

$ ed laws
188
1,$p        (Display the file)  
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
2,3c        (Change lines 2 and 3 for text to follow)  
This is a test of using the c command
.       (End data entry)  
1,$p        (Show the results)  
The laws of computer programming:
This is a test of using the c command
If a program is useless, it will have to be documented.
_

Text substitutions

Probably the most powerful feature of ed is its ability to perform global text substitutions. In its simplest form, a substitution is done using the s command, followed by two text patterns surrounded by a delimiter. The first text pattern represents the text to be replaced while the second string represents the new text, as in:

s/John/Mary/

The delimiter ("/" in the above example) can be any character, so long as it is not found in any of the text specified in the command. Traditionally, the forward slash is used as the delimiter but it could be almost anything else, such as a comma or even the letter "A."

In addition, you can specify a line number or a range of lines to perform this substitution on a block of text, as in:

2,5s/John/Mary/

To perform the substitution on the entire file, simply specify the range 1,$ like this:

1,$s/John/Mary/

For instance, let's change the word "useful" for "helpful" in our sample text file:

$ ed laws
188
1,$p        (Display the file)  
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
3s/useful/helpful/        (No output is shown unless we ask for it)  
p        (Tell ed to show the current line)  
If a program is helpful, it will have to be changed.
_

Note that, although the substitution was made, the line was not automatically displayed. To cause the line to be displayed after a substitution, you may tag the p instruction to the end of the command, like this:

s/useful/helpful/p

Deleting portions of text

To delete text from a line, simply substitute the text for nothing, as in:

s/John//

For instance, let's remove the word "given" from the first line of our sample file (note that we are now asking ed to display the result immediately by affixing the instruction "p" for "print" at the end of the substitution command):

$ ed laws
188
1,$p        (Display the file)  
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
2s/given//p
Any  program, when running, is obsolete.
_

Note that we now have two spaces between the words "Any" and "program", which may not be what we had intended. This is because we substituted only the word "given" for nothing, leaving the two surrounding spaces untouched. What we should have done is include one of these spaces in the text to be deleted, as in:

2s/given //p       (Note the space after "given")

Global Substitutions

Text substitutions are only performed on the first instance of the text pattern. For instance, when issuing the command:

s/John/Mary/

only the first instance of "John" is substituted for "Mary" on the line. If there are more instances of the word "John" on the line, these are left untouched.

You can cause ed to perform the substitution on the entire line by specifying the g modifier (for "global") at the end of the substitution command, as in:

s/John/Mary/g

Naturally, if you also want to see the result of the modification, you must add the p (for "print") modifier as well, as in:

s/John/Mary/gp

And if you want the substitution to affect a block of text, or the entire file, you must precede the instruction with the desired line range, as in:

1,$s/John/Mary/gp

As you can see, the syntax for global substitutions can become a little heavy. However, this syntax gives you perfect control over exactly how much text you are going to affect.

A word of caution is in order at this point. While global substitutions can be very powerful, you must be careful how you specify text patterns to avoid unexpected results. For instance, with the command:

    1,$s/John/Mary/gp

you would end up replacing "Johnny" for "Maryny", which may not be what you intented. Always be sure your text pattern is unique and unambiguous.

Un-doing changes

Another useful command is the u instruction, which stands for "undo". If you make a mistake, just enter u to undo the last change.

Note that entering u again will undo the "undo", reverting back to the original text.

 

 

Line Maneuvers

Now that we know how to create or delete lines of text as well as edit the word on existing lines, let's have a look at some standard maneuvers such as moving or copying blocks of text, splitting long lines, and joining lines together.

Splitting Lines

To split a long line, simply insert a carriage-return character at the desired point using a substitution. For instance, to split line 3 after the word "useless", simply substitute this word for the same word followed by a carriage-return.

To specify a carriage-return, use the backslash and press ENTER. The backslash, as we mentioned earlier, acts as an escape character which tells ed to take the next character "as is". This makes it possible to insert a carriage-return as part of our substitution, as shown in this example:

$ ed laws
188
3        (Make line 3 the current line and display it) 
If a program is useful, it will have to be changed.
s/useful, /useful, \
/        (The second part of our substitution command now includes a carriage-return)  
1,$p        (Look at the file now...) 
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful,
it will have to be changed.
If a program is useless, it will have to be documented.
_

Joining lines

The j command joins the current line to the next line. For instance, to join the two lines we just split up in the previous example, we would make line #3 the current line, then enter j, or jp to join and "print" the line to the screen, like this:

$ ed laws
188
3        (Make line 3 the current line and display it)  
If a program is useful,
jp        (Join and print)  
If a program is useful, it will have to be changed.
_

To join several lines, simply specify the desired range of lines, as in 1,3j.

Moving and Copying Text

The m instruction moves the specified line or range of lines after the line number specified to the m instruction. For instance, the command 2,3m$ moves lines 2-3 to the end of the file (i.e. after line "$").

$ ed laws
188
1,$p        (Display the file) 
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
2,3m$
1,$p
The laws of computer programming:
If a program is useless, it will have to be documented.
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
_

The t instruction copies text in the same manner. For instance, the command 2,5t0 copies lines 2-5 to the beginning of the file (i.e. after the imaginary "line 0").

$ ed laws
188
1,$p        (Display the file)  
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
2,3t0
1,$p
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
The laws of computer programming:
Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
_

 

 

Text Searches

Forward Search

It is possible to search for a given text pattern by simply surrounding this pattern within a pair of slashes, as in:

$ ed laws
188
/program/        (Search for a line containing the word "program")  
The laws of computer programming:
_

Note that ed searched for a simple text string, not necessarily the exact word. In this case, ed located the string "program" in the word "programming" and called it a match.

Backwards Search

Using question marks as the delimiter (as in ?program?) instead of slashes causes a backward search instead of a forward search.

Repeating the Search

You can seach for the next instance of this pattern by entering a single slash, which tells ed to search for the same string again, or a single question mark, which causes the search to resume backwards:

$ ed laws
188
/program/
The laws of computer programming
/        (Repeat the search)  
Any given program, when running, is obsolete.
/        (Next search...)  
If a program is useful, it will have to be changed.
/        (Again...)  
If a program is useless, it will have to be documented.
?        (Same search backwards...)  
If a program is useful, it will have to be changed.
_

Full Scan

Note that the entire file is always searched, whether the search is done backwards or forward. For instance, in the case of a forward search, ed will search from the current line all the way down to the end of the file and, if the pattern is not found, will start again from the top of the file down to the original starting position.

For backward searches, ed starts scanning text from the current line to the top of the file and, if the pattern has not been found, searches from the bottom of the file back to the current line.

The only difference is in the start direction for the search, not in the amount of text covered.

Context-Sensitive Commands

We have already seen how to apply an instruction on an entire block of text by specifying the range of lines to be affected.

For instance, to delete all text from lines 5 to 20 in a file, we would specify the line range like this:

5,20d

However, it is often useful to affect lines based on their contents, rather than their line number. For instance, we may want to delete all lines containing the word "discontinued" in a product catalogue.

For these situations, you can use the command g followed by the search pattern, followed by any desired action command (print, delete, substitute, etc.), as in these examples:

g/John/p Display all lines containing the word "John"
g/Discontinued/d Delete all lines containing the word "Discontinued"
g/Paris/s/wine/cheese/gp On all lines containing the word "Paris", substitute "wine" for "cheese" on the entire line (the "g" suffix) and display the new line (the "p" suffix).

Note the difference between "g" at the beginning of a line, which means "globally throughout the file, act on lines containing the following pattern", and the "g" at the end of the command, which means "perform the substitution on the entire line (globally over this line)". It is regrettable that the same letter was used for both these meanings, but they both mean "globally," although the prefix applies to the entire file while the suffix applies to the line.

 

 

Using ed in Real Life

When Would You Ever Use ed?

So, why did we bother learning a line-by-line editor? Surely, we'll never need to use this in today's GUI-based world.

Well, in fact, there are a number of cases where you might want or need to use ed:

  • As a system administrator, you may have to modify a configuration parameter on an unbootable system while working from an emergency boot CD. In these situations, you often have access to only a very limited set of commands, and ed might be the only editing tool at your disposal.
  • As a tech support person on the move, you might be connected remotely to a system in trouble using a tablet computer or even a smart-phone. Being so resourceful, you have managed to get an SSH connection to the system and are are sitting at a shell prompt, but your device does not properly emulate a terminal. You can still save the day by making the necessary editing changes using ed.
  • You might have a very slow connection to the system you need to configure, such as over an old-style telephone modem (shudder), and using ed would actually be less aggravating under these conditions than using a full-screen editor.

None of these scenarios seem likely to you? You may be right, but there is one last reason for using ed in real life: automated editing tasks using shell scripts. Let's have a look at this.

In-Place Editing

Like most other Unix utilities, ed reads its input from the standard input. Normally, this is the keyboard but it could be anything else, such as a file or a pipeline, using the shell's I/O redirection constructs (either the "<" construct or a pipe).

This means it is possible to "store" keystrokes in a file and use the shell's "<" construct to "feed" them to ed, like this:

$ ed samplefile < my_commands

In this example, we edited the file samplefile using commands stored in the file my_commands. Assuming this file contains valid ed commands, ed will execute them in exactly the same way as if they had been entered at the keyboard. In fact, ed has no way of knowing that these commands are not indeed entered from the keyboard.

For instance, the file my_commands could contain these instructions:

g/obsolete/d
w
q

These commands would cause ed to delete all lines containing the string "obsolete", then save the file (the "w" command) and quit (the "q" command).

All this would happen very quickly and all that would be displayed on the screen would be the number of characters read into the buffer and the number of characters written to the file at the end of the session, like this:

$ ed samplefile < my_commands
2043
1821
$ _

Another way to "feed" instructions to ed is to use echo to send the desired ed instructions to the standard output, then pipe those instructions to ed as in this example:

$ echo -e 'g/obsolete/d\nw\nq' | ed samplefile
2043
1821
$ _

We are getting the exact same result since the very same commands are being handed over to ed. The only difference in this case is that we used a pipeline instead of I/O redirection from a text file.

Note that the "\n" in the echo command generates a newline character and is equivalent to a carriage-return at the keyboard. This technique is used extensively in shell scripts to perform in-place editing of files.

Some Real-Life Examples

As a system administrator, you might have to sometimes perform some mass editing of user files to address various changes or upgrades on the system.

For instance, you might have a hundred user accounts who automatically login to a database application through a command in their .profile start-up file. Let's assume this command is "startdb" for the sake of illustration.

One day, you are informed that because of a recent upgrade, this command has become obsolete. Instead, users must now change directory to "/usr/local/db" and invoke a new program named "run_acct".

Your mission, if you choose to accept it, is to edit a hundred .profile files to reflect these changes. (Experienced system administrators will probably point out that there are better ways to log users directly into an application than to edit a bunch of .profile files, but let's just play along for the sake of this illustration.)

Assuming all your users have their home directories under /home, you could use a for loop to edit each file in succession, like this:

for x in /home/*/.profile
do
echo "g/startdb/d
a
cd /usr/local/db
run_acct
.
w
q" | ed $x
done

There it is! Within a second or two, you will have edited a hundred files. Let's examine this code in detail:

  • The for command is a shell construct that executes the code between the keywords do and done and sets the variable "x" to the value of each file that needs to be edited, in an iterative loop.
  • Within this loop, we use echo to feed commands to ed, one per line. Note that we are using double quotes to enclose the entire set of ed commands, closing them at the end (after the "q" instruction) before piping the whole thing to ed. The result is the same as if we had typed these commands at the keyboard, one per line.
  • The first instruction says "globally throughout the file, wherever you find the string startdb, delete the line."
  • The next instruction is a on a line by itself, which tells ed to append the following text. By then, the current line is the line where startdb used to be, so all subsequent text will be inserted into the file at that point.
  • The next two lines of text are the new instructions we want to enter in the user's .profile file. The first command takes them to the /usr/local/db directory, while the next command invokes the application.
  • After entering the desired text, we feed ed a single dot on a line by itself, which indicates we are finished entering text. At this point, ed returns to command mode.
  • Finally, we feed ed the instructions w and q to write the changes and quit.
  • The next iteration of the for loop will invoke ed again on the next file, and this process is repeated (very quickly) until every file has been edited.

The above example assumes you are familiar with shell programming. If the constructs used in this example are unfamiliar to you, look for an upcoming Shell Programming tutorial on this site.

Here is another example. You might have a system log that needs to be periodically archived but you want to eliminate certain superfluous lines from the log before archiving it. In addition, you won't need to archive the entire log but rather only the first 100 lines since the rest is assumed to be repetitions or irrelevant for whatever reason.

For the sake of this illustration, let's say this log is generated daily, contains thousands of lines, and must be purged of every line containing the string "admin5", and then truncated to only the first 100 lines before being sent to archives.

To do this, you could set up a shell script to run every day, containing something like this:

echo "g/admin5/d
101,$d
w
q" | ed the_log_file

Here is what we have done:

  • The first command, "g/admin5/d" tells ed to scan the entire file for any line containing the string "admin5" and to delete such lines. (If you think this would also delete lines containing the string "admin51," "admin52," etc., you are right. We will address this issue shortly.)
  • By the time we get to the second instruction, the file has been purged of all lines containing the string "admin5." We then tell ed to delete from line 101 to the last line ("$"), leaving only the first 100 lines in the file.
  • The last two instructions tell ed to save the file and quit.

Using "Wild-Card" Expressions

So far, all the examples we have used in this tutorial involving text searches featured fixed strings. However, it is possible (and common) to use "wild-card" text patterns in searches to substantially increase the usefulness of these searches.

For instance, instead of searching for "admin5" in our previous example, we might have wanted to search for either "admin5" or "Admin5" (capitalized), and we might also want to make sure we do not pick up strings like "admin51" and "admin51" in the process. Or perhaps we only want to delete lines that start with admin5, ignoring the line if this string is found anywhere else on the line.

Most text-oriented utilities in Linux, such as ed, grep, and awk support a sophisticated set of wild-card characters called regular expressions, making these utilities extremely useful and powerful for programming and system administration tasks. Using regular expressions, we could address each one of the situations we just outlined.

Regular Expressions are outside the scope of this tutorial but are covered in a separate tutorial on this site. If you are serious about managing Linux system or writing shell scripts, you absolutely must learn about regular expressions; this will be one of the most useful tools in your administrator's toolkit and will serve you for the rest of your programming career.

 

 

Summary

The ed text editor is a command-driven utility to create or modify text files. ed accepts commands in the form:

<line_number(s)><command>

where <line_number(s)> is either a single line number or a range of lines expressed as two numbers separated by a comma, and <command> is an editing instruction.

The most common ed commands are:

p Display text ("print")
d Delete line(s)
c Change line(s)
s Substitute text
i Insert text above the current line
a Append text below the current line
. (dot) End text entry
j Join lines
m Move lines
t Copy ("transpose") lines
u Undo last change
w Save ("write") the file
q Quit the editor

Text substitutions performed with the s command affect only the first instance of the text found on a line; to cause the entire line to be affected, the suffix 'g' must be added, as in:

s/John/Mary/g

To display the line after a substitution, the suffix 'p' must be added, as in:

s/John/Mary/p

The m and t commands may be used to move or copy blocks of text to a different line number. For instance, 2,3m$ moves lines 2 and 3 to the end of the file, while 15,20t5 copies the lines 15-20 right after line 5 in the text.

It is possible to search for text by bracketing the desired search string between slashes, as in:

/John/

Using the forward slashes causes ed to search forward through the file. To do a backwards search, bracket the search string with a pair of question marks instead, as in:

?John?

The search can be repeated by entering a single slash or question mark, depending on whether you want to search forward or backwards through the file, respectively.

It is possible to issue editing instructions which will affect only lines containing a specific text pattern by preceding the instruction with the command g followed by the text pattern between slashes, as in:

g/John/d

This example can be read like this: "Globally, wherever the word John is found, delete the line."

The command can be any valid editing instruction, such as p to display the lines matching the pattern, or s to perform a text substitution on these lines.

The ed editor supports wild-card characters which can be used in text searches and global text substitutions. These are called Regular Expressions and are common across many text-oriented Linux utilities such as grep, sed, awk, tr and expr, but are different from the shell's wild-card characters in some ways.

 

 


Did you find an error on this page or do you have a comment?

Services
Sponsors