ServerAID
Найти гайд, команду, тег… ⌘ K
Shell и скрипты

Команды 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.

Похожие материалы

Shell и скрипты

Как распаковать tar.gz в Linux через терминал: tar, zip, xz и другие форматы

Короткий ответ — tar -xzf archive.tar.gz. Дальше разбираем, что означает каждая буква, как распаковать в нужный каталог, посмотреть содержимое до распаковки, вытащить один файл из большого архива и не поймать «tar-бомбу», которая раскидает сотни файлов по текущему каталогу.

Редакция
Shell и скрипты

Команда lsblk в Linux: как посмотреть диски, разделы и точки монтирования

lsblk показывает все блочные устройства сервера деревом: диски, разделы, LVM-тома, шифрованные контейнеры и куда они смонтированы. Разбираем колонки вывода, флаг -f для файловых систем и UUID, свои наборы колонок через -o и типовые задачи — найти новый диск, собрать строку для fstab, понять структуру LVM.

Редакция
Shell и скрипты

Как скопировать файл в Linux через терминал: cp, rsync и scp с примерами

Разбираем копирование в терминале: cp для файлов и каталогов, флаг -a для сохранения прав и симлинков, rsync для больших объёмов и докачки, scp для переноса на другой сервер. Плюс ловушки со слэшем в конце пути и скрытыми файлами, на которых теряют данные.

Редакция
Shell и скрипты

Как удалить файл или каталог в Linux через терминал: rm, rmdir и безопасные привычки

Разбираем удаление в терминале: rm для файлов, rmdir для пустых каталогов, rm -r для каталогов с содержимым. Отдельно — чем опасен rm -rf, как удалить файл со странным именем, почему после удаления не освободилось место и как настроить автоочистку старых логов.

Редакция