Команды vi в Linux: режимы, навигация, поиск и замена — шпаргалка
Начнём с главного: выйти из vi — это Esc, затем :q! без сохранения или :wq с сохранением. Дальше — рабочий минимум команд, которого хватает для правки конфигов на сервере: режимы, перемещение, удаление и вставка, поиск с заменой и трюк для сохранения файла, который открыли без sudo.
vi есть на любом сервере — в минимальной установке Ubuntu, в контейнере, в спасательном режиме. Ставить туда nano не всегда возможно, поэтому рабочий минимум команд vi стоит знать даже тем, кто редактирует конфиги раз в месяц.
Как выйти из vi
Начнём с вопроса, ради которого сюда чаще всего и приходят. Нажмите Esc — это возвращает в командный режим из любого состояния, — а затем:
| Команда | Что делает |
|---|---|
:q |
Выйти, если ничего не меняли |
:q! |
Выйти без сохранения, отбросив изменения |
:wq |
Сохранить и выйти |
:x |
То же, но записывает файл только если были изменения |
ZZ |
Сохранить и выйти (без двоеточия) |
ZQ |
Выйти без сохранения (без двоеточия) |
Если :q отвечает No write since last change, значит файл изменён — либо сохраняйте (:wq), либо выходите принудительно (:q!).
Если двоеточие не появляется в нижней строке, вы всё ещё в режиме вставки: нажмите Esc и повторите.
Режимы — главная идея редактора
Непривычность vi в том, что клавиши делают разное в зависимости от режима.
Командный режим (normal) — режим по умолчанию, в него возвращает Esc. Буквы здесь не печатаются, а выполняют команды: x удаляет символ, dd — строку.
Режим вставки (insert) — обычный ввод текста. Вход по i, выход по Esc. Внизу экрана видно -- INSERT --.
Командная строка (ex) — открывается двоеточием. Здесь живут :w, :q, поиск с заменой и настройки.
Визуальный режим (visual) — выделение текста, вход по v. Есть только в vim, в классическом vi его нет.
Практическое правило: не уверены, где находитесь, — нажмите Esc дважды.
Входим в режим вставки
| Клавиша | Куда попадает курсор |
|---|---|
i |
Перед текущим символом |
a |
После текущего символа |
I |
В начало строки (перед первым непробельным) |
A |
В конец строки |
o |
Новая строка ниже |
O |
Новая строка выше |
A и o экономят больше всего времени: дописать в конец строки или добавить строку под текущей — самые частые операции при правке конфигов.
Перемещение по файлу
Стрелки в vim работают, но привыкать лучше к базовым клавишам — они есть везде и не требуют убирать руки:
h влево j вниз k вверх l вправо
Более крупные шаги:
| Команда | Перемещение |
|---|---|
w / b |
На слово вперёд / назад |
e |
В конец текущего слова |
0 |
В начало строки |
^ |
К первому непробельному символу строки |
$ |
В конец строки |
gg |
В начало файла |
G |
В конец файла |
42G или :42 |
На строку 42 |
Ctrl+f / Ctrl+b |
Страница вперёд / назад |
Ctrl+d / Ctrl+u |
Полстраницы вниз / вверх |
% |
К парной скобке |
Ctrl+g |
Показать имя файла и позицию |
Переход к строке по номеру нужен постоянно: nginx -t сообщает об ошибке в строке 42 — набираете :42 и оказываетесь на месте.
Удаление, копирование, вставка
| Команда | Действие |
|---|---|
x |
Удалить символ под курсором |
dw |
Удалить слово |
dd |
Удалить строку целиком |
D |
Удалить от курсора до конца строки |
yy |
Скопировать строку |
yw |
Скопировать слово |
p |
Вставить после курсора (строку — ниже) |
P |
Вставить перед курсором (строку — выше) |
u |
Отменить последнее действие |
Ctrl+r |
Повторить отменённое |
. |
Повторить последнюю команду |
В vi удаление и копирование работают в один буфер, поэтому dd + p — это «переместить строку».
Команды умножаются числом:
3dd удалить три строки
5yy скопировать пять строк
2dw удалить два слова
10j спуститься на десять строк
Замена без лишних шагов:
| Команда | Действие |
|---|---|
r + символ |
Заменить один символ под курсором |
cw |
Заменить слово (удалить и перейти в режим вставки) |
cc |
Заменить строку целиком |
C |
Заменить от курсора до конца строки |
Точка (.) повторяет последнее изменение — в связке с поиском это самый быстрый способ сделать однотипные правки в нескольких местах.
Поиск
/текст искать вперёд
?текст искать назад
n следующее совпадение
N предыдущее
* искать слово под курсором
Поиск понимает регулярные выражения:
/^server строки, начинающиеся с server
/timeout$ строки, заканчивающиеся на timeout
/error\|warn error или warn
Подсветку найденного включает :set hlsearch, снимает — :noh. Регистронезависимый поиск — :set ignorecase.
Поиск с заменой
Синтаксис команды замены — как у sed, потому что оба выросли из одного предка:
:s/старое/новое/ первое совпадение в текущей строке
:s/старое/новое/g все совпадения в текущей строке
:%s/старое/новое/g все совпадения во всём файле
:%s/старое/новое/gc то же, но с подтверждением каждой замены
:10,20s/старое/новое/g только в строках с 10 по 20
% означает «весь файл», g — все вхождения в строке, c — спрашивать подтверждение.
Если в тексте есть слэши (например, в путях), удобно взять другой разделитель:
:%s#/var/www/old#/var/www/new#g
Реальный пример — заменить порт во всём конфиге:
:%s/8080/9090/gc
Работа с файлом
| Команда | Действие |
|---|---|
:w |
Сохранить |
:w имя |
Сохранить под другим именем |
:e файл |
Открыть другой файл |
:e! |
Перечитать файл с диска, отбросив изменения |
:r файл |
Вставить содержимое файла в текущую позицию |
:r !команда |
Вставить вывод команды |
Последнее удобно, когда нужно вставить в конфиг результат выполнения — например, :r !date.
Забыли sudo — не переоткрывайте файл
Классическая ситуация: открыли vi /etc/nginx/nginx.conf без sudo, всё поправили, а :w отвечает Can't open file for writing или readonly option is set.
Не теряйте правки. В командном режиме:
:w !sudo tee % > /dev/null
Здесь % — имя текущего файла, tee записывает его с правами root, > /dev/null глушит лишний вывод. Редактор спросит пароль, затем предложит перечитать файл — отвечайте L (load). Механика ровно та же, что при создании файлов от root, — она разобрана в статье про создание файла в терминале.
Работает трюк только там, где ваш пользователь имеет право на sudo.
Несколько файлов и окна
:sp файл горизонтальное разделение окна
:vs файл вертикальное разделение
Ctrl+w w переключиться между окнами
Ctrl+w q закрыть текущее окно
:bn / :bp следующий / предыдущий буфер
:ls список открытых буферов
Сравнивать два конфига удобно так:
vimdiff /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
Различия подсвечиваются, ]c и [c прыгают между ними.
vi, vim и vim.tiny в Ubuntu
В минимальной установке Ubuntu Server команда vi — это, как правило, vim.tiny: урезанная сборка без визуального режима, подсветки синтаксиса и многоуровневой отмены. Отсюда сюрприз: u отменяет только одно последнее действие, а стрелки в режиме вставки печатают буквы.
Проверить, что стоит:
readlink -f $(which vi)
vim --version | head -1
Полноценный редактор ставится обычным пакетом:
sudo apt install vim
После установки vi продолжит указывать на выбранную альтернативу; сменить её можно так:
sudo update-alternatives --config vi
Минимальный ~/.vimrc
Несколько строк, которые заметно облегчают правку конфигов:
set number " номера строк
set hlsearch " подсветка результатов поиска
set incsearch " поиск по мере ввода
set ignorecase " игнорировать регистр
set smartcase " ...но учитывать, если есть заглавные
set expandtab " Tab вставляет пробелы
set tabstop=4
set shiftwidth=4
syntax on " подсветка синтаксиса
set mouse= " отключить мышь, чтобы работало копирование терминалом
Файл создаётся в домашнем каталоге:
vi ~/.vimrc
Последняя строка часто спасает: в свежих версиях мышь включена по умолчанию, и выделение текста мышью попадает в редактор вместо буфера терминала.
Шпаргалка: минимум для сервера
Esc выйти в командный режим
i / A / o вставка: здесь / в конец строки / новой строкой ниже
:42 перейти на строку 42
dd / 3dd удалить строку / три строки
yy / p скопировать строку / вставить
u / Ctrl+r отменить / вернуть
/текст n найти / следующее совпадение
:%s/a/b/gc заменить во всём файле с подтверждением
:w :q! :wq сохранить / выйти без сохранения / сохранить и выйти
:w !sudo tee % сохранить, если забыли sudo
Частые вопросы
Как выйти из vi, если ничего не работает?
Нажмите Esc — возможно, дважды, — а потом наберите :q! и Enter. Это выход без сохранения, он срабатывает всегда, независимо от того, что успели поменять.
Если вместо двоеточия в файл печатаются символы, значит Esc не сработал: нажмите его ещё раз и повторите. В совсем безвыходной ситуации помогает Ctrl+c, а затем :q!.
Чем vi отличается от vim?
vi — исторический редактор из Unix, vim (Vi IMproved) — его расширенная версия: визуальный режим, многоуровневая отмена, подсветка синтаксиса, разделение окон.
В Ubuntu команда vi обычно указывает на vim.tiny — урезанную сборку. Полный редактор ставится пакетом vim, после чего доступны все возможности.
Как в vi заменить текст во всём файле?
Командой :%s/старое/новое/g — % означает весь файл, g — все вхождения в каждой строке. Добавьте c (:%s/старое/новое/gc), чтобы подтверждать каждую замену.
Если в тексте есть слэши, смените разделитель: :%s#/old/path#/new/path#g.
Как сохранить файл в vi, если открыл его без sudo?
Наберите :w !sudo tee % > /dev/null — файл запишется через tee с правами root, а правки не потеряются. На вопрос о перезагрузке файла ответьте L.
Работает только если у пользователя есть право на sudo. Если его нет, сохраните копию в свой каталог: :w ~/config-backup.
Как включить нумерацию строк в vi?
В командном режиме — :set number (или коротко :set nu), отключить — :set nonumber. Настройка действует до выхода из редактора.
Чтобы включалась всегда, добавьте строку set number в файл ~/.vimrc.
Что запомнить
Escвозвращает в командный режим из любого места;:q!выходит без сохранения,:wq— с сохранением.- Команды умножаются числом:
3ddудалит три строки,5yyскопирует пять. :%s/старое/новое/gc— замена по всему файлу с подтверждением каждой правки.:w !sudo tee %спасает изменения, если файл открыли безsudo.- В минимальной Ubuntu
vi— этоvim.tinyс урезанной отменой и без визуального режима; полный редактор ставится пакетомvim.