Mastering the Essential Vi Editor Commands for Efficient Linux Text Editing
SSH into almost any production server—RHEL 7.x, Ubuntu 22.04 LTS, or legacy Solaris—and one tool is always available: Vi. While some teams standardize around Vim (Vi Improved) for its extended functionality, classic Vi (typically version 2.0 or older, or vim in -u NONE
mode) remains indispensable where minimalism, predictability, and stability are non-negotiable.
Why Vi, not nano or emacs?
- Ubiquity: Pre-installed on every POSIX-compliant system.
- Minimal footprint: <1 MB binary, no config or plugin dependencies by default.
- Reliable in recovery/maintenance modes—even when $TERM is restricted, or
/usr/local
is unavailable.
Core Concepts: Modes and Mental Models
At first, Vi’s modal interface trips up newcomers. Instead of toggling editing with the mouse, Vi operates with two main states:
- Normal (Command) Mode: Keystrokes are commands (e.g.,
dd
,x
,:wq
). - Insert Mode: Text entry as expected; reached with commands like
i
,a
, oro
.
Returning to command mode is non-negotiable before executing most operations—always press ESC
to reset state. If your terminal beeps, you’re still not in normal mode.
Common Startup Patterns
Editing /etc/ssh/sshd_config
on a newly provisioned Debian host—vi /etc/ssh/sshd_config
. If the file is missing, Vi opens a new buffer, but writes will fail unless permissions and paths are correct.
Permissions issue? Expect:
E212: Can't open file for writing
A simple habit: prefix with sudo
only when necessary; otherwise, you risk partial writes if you forget to escalate.
Navigation and Editing: Commands in Practice
Table 1 outlines navigation you’ll use daily:
Command | Use Case |
---|---|
h /j /k /l | Precise left/down/up/right (works when arrow keys fail over SSH) |
w /b | Next/previous word boundary |
0 /$ | Start/end of current line |
G | Go to file end (gg for top) |
/pattern | Forward search |
Text insertion varies:
i
— Before cursor (insert)a
— After cursor (append)o
— Open below (rarely,O
above)I
/A
— Start/end of line
Deleting is direct:
x
— Remove character under cursordd
— Yank (cut) entire lined$
— Delete to line enddw
— Delete word (gotcha: stops at punctuation)
Undo/redo:
u
— Single-level undoCtrl+r
— Redo (only in Vim, not always in classic Vi).
— Repeat last change
Saving/exit workflow:
:w
— Write buffer:q
— Quit:wq
/ZZ
— Write and quit (faster than:wq
):q!
— Quit, discard changes
Note: on systems with minimal Vi, ZZ
is safest for atomic write+exit; :x
is equivalent but less portable.
Practical Workflow: Small but Critical Edits
Suppose you’re patching a typo in /etc/fstab
before remounting disks:
sudo vi /etc/fstab
- Navigate using
/mnt
to find disk entries. - Use
j
/k
if arrow keys misbehave over certain SSH clients. - Correct errors:
i
, fix, thenESC
. - Yank and paste (
yy
,p
) to duplicate similar lines. - Save and exit fast:
ZZ
.
If you see E45: 'readonly' option is set
, drop to shell, run with sudo
or :w!
for forced write—Vi won’t warn you earlier.
Non-Obvious Techniques
Global Search & Replace
Replacing every “host01” with “host02”, including commented lines:
:%s/host01/host02/g
To restrict within line range 10–20:
:10,20s/foo/bar/gc
Appends c
for confirmation per occurrence.
Visual Marking (Vim only, not in classic Vi):
v
/V
to select, then run commands (e.g.,d
to delete).
Not present in historic Vi. When in doubt, stick to yank/delete by line.
Side Note: When Vi Fails
Terminal type not set?
E558: Terminal entry not found in termcap
Set export TERM=xterm
or use a basic client.
Clipboard operations don’t work on remote SSH by default—copy from terminal, not from Vi.
Closing Thoughts
Vi isn’t intuitive—nor does it try to be. It’s designed for agility and availability under constraints. Invest time in the core workflows above. The rest (macros, registers, scripting support) can be ignored for most ops use-cases, unless you’re automating mass changes or refactoring code in bulk.
For configuration file recovery and live ops, nothing matches the speed of Vi. Refine muscle memory, accept the modal quirks, and remember: every Linux admin has misfired a :q
before a save at least once. Learn, adapt, and keep /usr/bin/vi
in your toolbox—even if your editor of choice is something else.
Further reading:
man vi
(for minimal Vi)vimtutor
(for Vim-specific enhancements)/usr/share/doc/vim-*
for platform differences
+------------------------------+
| vi |
| (no mouse, no GUI, no fuss) |
+------------------------------+