Module 3 · Text, redirection and pipes
The vi editor, part 2: editing, searching, replacing
Delete, copy and paste lines, repeat commands with counts, search with /, and run the :s substitution that fixes a whole file in one line.
What you will learn
- Delete, yank and put text with x, dd, dw, yy and p, with counts.
- Search forward and backward with / and ?, and jump between matches with n and N.
- Replace text on one line or in the whole file with :s and :%s, with and without the g flag.
Once you can get in and out of vi, its real strength appears: in command mode, editing is a tiny language. A command like dd is a verb (d, delete) applied to a target (d again, the line). Put a number in front and it repeats: 3dd deletes three lines. Learn a handful of verbs and targets and you can express most edits in two or three keystrokes, without ever reaching for the mouse.
Deleting, copying, pasting
| Keys | Effect |
|---|---|
x | delete the character under the cursor |
dw | delete to the end of the word |
dd / 3dd | delete the line / three lines |
D | delete to the end of the line |
yy / 3yy | yank (copy) the line / three lines |
p / P | put the last deleted or yanked text after / before |
u | undo |
. | repeat the last change |
Deleted text is not lost: dd followed by p moves a line down one position, and yy then p duplicates it. That is how cut, copy and paste work in vi: delete or yank, move, put. r followed by a character replaces the one under the cursor, and cw changes a word (deletes it and enters insert mode) — handy when a value needs retyping.
Searching
Type / followed by the text and Enter to jump to the next occurrence; ? searches backward. n repeats the search in the same direction and N in the opposite one. The pattern is a regular expression, the subject of lessons 33 and 34, so . and * are special; for a literal dot write \.. Searching is also the fastest way to move: /port lands you on the line you want in a long config file far quicker than scrolling.
Substituting with :s
:s/old/new/ replaces the first old on the current line with new. Add g at the end to replace every occurrence on the line. Put a range in front to cover more lines: :%s/old/new/g is the whole file, :1,10s/old/new/g lines 1 to 10. This is the single most useful command in vi, and it is the same syntax sed uses (lesson 39), so learning it pays twice.
~% cat notes.txt
status: draft
title: Draft notes
status: draft
~% vi notes.txt
:%s/draft/final/g # every lowercase "draft" in the file
:wq
~% cat notes.txt
status: final
title: Draft notes
status: final
~% vi todo.txt
/REMOVE # jump to the line containing REMOVE
dd # delete it
:wq
Running vi without the keyboard
vi -c CMD file runs a colon command as soon as the file opens. Chain -c ':%s/a/b/g' -c ':wq' and vi edits and exits by itself, which is useful in scripts and is the form the solutions in this lesson use so they can be checked automatically. Interactively you would type the same commands yourself.
Commands in this lesson
| Command | What it does |
|---|---|
x dw dd D | Delete a character, a word, a line, to end of line. |
yy p P | Copy a line; paste after / before. |
3dd | Delete three lines (any command takes a count). |
/text n N | Search forward; next match; previous match. |
:s/old/new/ | Replace first match on the current line. |
:%s/old/new/g | Replace every match in the whole file. |
:5d | Delete line 5 from the colon prompt. |
vi -c ':%s/a/b/g' -c ':wq' file | Run colon commands on open, non-interactively. |
Quiz
What does `3dd` do?
- Deletes three characters
- Deletes three lines starting at the cursor
- Goes to line 3
Which command replaces every `foo` with `bar` in the whole file?
- `:s/foo/bar/`
- `:%s/foo/bar/g`
- `/foo/bar`
After `/error` finds a match, how do you jump to the next one?
- `n`
- `N`
- Enter
How do you move the current line one position down?
- `dd` then `p`
- `yy` then `p`
- `x` then `P`
What does `:%s/draft/final/` (no g) change?
- Only the first `draft` of the whole file
- The first `draft` on each line of the file
- Every `draft` everywhere
Practice
In /root/lab/l29/notes.txt, replace every lowercase `draft` with `final` throughout the file (leave `Draft` with a capital D as it is) and save.
/root/lab/l29/todo.txt has three lines; the second one says `REMOVE ME`. Delete that line with vi and save, leaving the other two untouched.
In vi command mode, what do you type to search forward for the word `error`?
Open this lesson in the app to do the tasks in a real Linux machine and have them checked.