Next Previous Contents

## 9. Руководство по Vi

В этом пособии,описываются некоторые "продвинутые" команды и концепции vi, так, чтобы вы могли оценить всю мощь vi и продумать какие команды вам необходимо изучить в первую очередь. Почти все руководства по vi перечисляют доступные команды, но не показывают их взаимосвязи;это и есть основное предназначение данного руководства.

## 9.1 Команды перемещения курсора

Команды vi для перемещения курсора,позволяют позиционировать курсор в файле и/или на экране эффективно,с минимальным количеством нажатий клавиш. Существует огромное количество команд перемещения курсора - не пытайтесь запомнить их все сразу ! Позже вы увидите,что мощь vi заключается в комбинации команд передвижения курсора с командами для удаления,изменения,копирования и фильтрования текста.

Пожалуйста выберите какой нибудь большой текст,чтобы вы смогли проэкспериментировать с каждой из описанных команд. Также помните,что эти команды будут работать только в командном режиме,не в режиме вставки;если вы начали вводить эти команды прямо в текст - нажмите ESC чтобы вернуться в командный режим.

- Клавиши-стрелки : Клавиши со стрелками перемещают курсор на одну позицию влево,вправо,вверх или вниз. Перемещение выше начала файла,ниже его последней линии или перемещение влево или вправо (автоматический перенос) за край строки не разрешены.

- hjkl : Когда vi был написан (примерно в 1978), многие терминалы на UNIX системах не имели клавиш-стрелок! h, j, k, и l были выбраны как команды для перемещения влево,вниз,вверх и вправо соотвественно. Попробуйте их! Большинство vi профессионалов предпочитают их, курсорным клавишам потому-что
  - (а) они располагаются одинаково на всех типах клавиатуры, и
  - (б) они приятней для пальцев, чем большинство курсорных клавиш, которые расположены ввиде "T" или другой нелинейной форме.
  Почему h, j, k, и l? Хорошо, в наборе символов ASCII , CTRL-H это backspace (перемещение влево), CTRL-J это linefeed (перемещение вниз), и, конечно, k и l расположены за h и j,поэтому их легко запомнить.

- 0 : ("ноль", не "о") Перемещает курсор к началу текущей линии. (Чтобы попробывать эту и несколько последующих команд,используйте h j k l или клавиши со стрелками,чтобы перейти к строке с отступом,которая содержит несколько "е". Если вы не найдете такой строки - создайте её сами, вставив несколько пробелов в начало строки.

- ^ : Передвигает курсор на первый символ,не являющийся пробелом,в текущей строке.(Для строки с отступом, команды 0 и ^ действуют по разному).

- $ : Перемещает курсор на последний символ текущей строки.

- tC : Передвигает к (не "на") следующий символ "c" в текущей строке. (Нажмите 0, а затем te. Это переместит вас к первой "e" в текущей строке.)

- fC : Находит (перемещает "на") первый символ "c" в текущей строке. (Нажмите fe, и курсор найдет (переместиться на позицию) следующего символа "e" в текущей строке.)

- TC : Передвигает к (но не "на") преведущий символ "c" в текущей строке. (Нажмите $, затем Te.)

- FC : Находит (передвигает "на") преведущий "c" в текущей строке. (Нажмите Fe.)

- n| : Передвигает к колонке к колонке n в текущей строке. (Попробуйте 20 |. Цифры 2 и 0 не будут отображаться во время ввода, но когда вы нажмете | курсор переместиться к колонке 20.) Попробуйте поэксперементировать с t f T F |. Когда вы сделаете что нибудь неправильное,vi сообщит вам о этом звуковым сигналом.

- w : Перемещает курсор вперед к началу следующего "маленького" слово ("маленькое" слово - состоит из символов алфавита и цифр не "разорванных" пробелом или знаков пунктуации, но не их смеси). Попробуйте нажать w несколько раз,чтобы понять как работает эта команда.

- W : Перемещает курсор вперед к началу следующего "большого слова"(смесь алфавитно-цифровых символов и пунктуации). Попробуйте применить эту команду несколько раз.

- b : Назад к началу "маленького" слова.

- B : Назад к началу "большого" слова.

- e : Вперед к концу "маленького" слова.

- E : Вперед к концу "большого" слова.

- + Enter : Передвигает курсор к первому символу (не пробелу) на следующий строке. (+ и Enter имеют одинаковый эффект)

- - : Передвигает курсор к первому символу (не пробелу) на преведущей строке.

- ) : Перемещает курсор к концу предложения. (Предложение кончается либо на пустой строке либо точкой или вопросительным/восклицательным знаком после которых идут два пробела,или на конце строки. Точка или восклицательный знак с пробелом после них,не заканчивают предложение;это корректное поведение,основанное на классических правилах составления печатных документов,хотя оно часто кажеться неправильным людям, которые не когда не изучали правила набора.)

- ( : Перемещает курсор к началу предложения.

- } : Перемещает курсор к концу параграфа. (Параграфы разделяются пустыми строками по определению,используемому vi)

- { : Перемещает курсор к началу параграфа.

- H : Отправляет курсор на первую строку видимую на экране.

- M : Отправляет курсор на среднюю строку видимую на экране.

- L : Передвигает курсор к последней строке видимой на экране.

- nG : Перемещает курсор на строку n. Если n не задано, передвигает на последнюю строку файла. (Например: попробуйте 15G чтобы перейти к 15й линии. Комбинация CTRL-G отображает имя файла, некоторую информацию о нем, и номер текущей строки. Чтобы перейти к началу файла нажмите: 1G)

- CTRL-d : Скроллирует вниз половину экрана (смотрите примечание).
- CTRL-u : Скроллирует вверх половину экрана (смотрите примечание).
- CTRL-f : Перемещает курсор вперед на один экран (смотрите примечание).
- CTRL-b : Перемещает курсор на один экран назад (смотрите примечание).
- Примечание : Эти четыре команды для скроллинга не могут быть использованы совместно с командами удаления,изменения,копирования или фильтрования.

- /регулярное_выражение : Перемещает курсор к следующему регулярному выражению. Когда вы нажимаете /,курсор перемещается на командную строку и vi ждет ввода выражения Нажмите Enter чтобы завершить ввод;vi начнет поиск регулярного выражения вперед по тексту. Например введите /ро и нажмите Enter. Это передвинет курсор к первому "ро" встреченному при поиске вперед по тексту. Если вы просто введете / и нажмете Enter - vi начнет поиск выражение которые вы искали в последний раз.

- n : Имеет тот же эффект что и нажатие / и Enter; т.е., ищет то выражение которое было аргументом для команды поиска в последний раз.

- ?регулярное_выражение : Ищет в обратном направлении. Если регулярное выражение не указано то производиться поиск аргумента последней операции поиска. Обе операции поддерживают автоматический перенос,т.е. поиск за "границами" файла разрешен.

- N :Тоже самое что ? и Enter.

## 9.2 Коэффициент повторения

Многие из приведенных выше команд перемещения курсора могут быть предварены коэффициентом повторения;в таком случае команда просто повторяется несколько раз.

- 3w : Передвигает курсор вперед на три слова
- 5k : Переходит вверх на пять символов
- 3fa : Находит третье "а" в текущей строке
- 6+ : Переходит вниз на шесть линий

Для некоторых комманд коэффициент повторения имеет особое значение.

- 4H : Переходит на четвертую строку видимую на экране
- 8L : Переходит к восьмой строке от края(низа) экрана
- 3$ : Переходит к концу третьей строки (вниз)

Для некоторых комманд (например, ^) коэффициент повторения игнорируется; для других (например., / и ? ) он применяться не может.

## 9.3 Удаление текста

Мы уже видели,что dd удаляет текущую строку. Эту команду можно использовать совместно с коэффициентом повторения: 3dd удаляет три строки, текущую и две следующих.

Команда d может быть использована совместно с практически любой командой перемещения по тексту, что позволяет удалять произвольные фрагменты текста. При использование совместно с d команды перемещения называются спецификаторами цели. (во время экспериментов со следующими примерами, не забывайте нажимать u чтобы восстанавливать то-что вы удалили).

- dw : Удаляет следующее "маленькое" слово
- d3w : Удаляет три следующих "маленьких" слова
- 3dw : Три раза удаляет следующее "маленькое" слово
- 3d3w : Три раза удаляет три следующих "маленьких" слова (т.е. удаляет девять "маленьких" слов)
- d+ : Удаляет текущую строку и следующую за ней
- d/the : Удаляет текст начиная с текущего положения курсора вплоть до первого встреченного "the", не включая его .
- d$ : Удаляет до конца строки
- d0 : Удаляет до начала строки
- d30G : Удаляет от текущей строки до 30 строки (включая её)
- dG : Удаляет от текущей строки до последней (включая её)
- d1G : Удаляет от текущей строки до строки номер 1 (включая её)

Для удаления одного символа используйте x. x можно использовать совместно с коэффициентом повторения.

- 15x : Удаляет текущий и 14 последующих символов

x на самом деле - макрос для d1; удаление одного символа.

## 9.4 Изменение текста

Команда c в основном идентична d, исключая то,что она переключает vi в режим вставки,позволяя изменить изначальный текст на что то другое.

Например : разместите курсор на начале какого-либо слова (нажмите w чтобы перейти к началу следующего слова). Затем нажмите cw , чтобы изменить это слово.На экране последний символ заменяемого слова будет изменен на $, индицирующий границы производимых изменений; попробуйте ввести новое слово и нажмите ESC когда закончите.Новый фрагмент текста может быть длинее/короче чем тот который был удален.

Поместите курсор на начале строки содержащей как минимум три слова, и попробуйте c3w для изменения этих слов. Попробуйте $ чтобы изменить текст до конца текущей строки. Во всех случаях когда изменение касается только текущей строки конец изменяемого текста помечается символом $.

Когда изменение касается не только текущей строки,vi удаляет оригинальный текст и переходит в режим вставки. Например попробуйте c3+ для изменения текущей и трех последующих строк;vi удалит четыре оригинальных строки на экране и перейдет в режим вставки на новой пустой строке. Как и обычно нажмите ESC чтобы вернуться в командный режим.

Некоторые примеры команд изменения:

- cc : Изменяет текущую строку
- 5cc : Изменяет пять строк (текущую и четыре следующие)
- c/the : Изменяет текст с текущего символа вплоть до (но не включая) следующего встреченного в тексте the
- c$ : Изменяет до конца строки
- c30G : Изменяет от текущей до строки номер 30, включая её
- cG : Изменяет от текущей до последней строки, включая её
- c1G : Изменяет от текущей строки до строки номер 1, включая её

## 9.5 Копирование текста

Команда y копирует фрагмент текста в буфер;из буфера скопированный текст может быть вставлен в любую часть файла используя команду p или P.

Самая простая форма копирования - скопировать текущую строку;введя yy, попробуйте p, чтобы вставить копию скопированной строки после курсора. Вы можете вставить эту строку в файл столько раз, сколько это необходимо, перемещаясь по файлу и нажимая p.

Чтобы скопировать множество строк, попробуйте, например, 5yyy (копирует текущую строку и следующие четыре строки). p вставляет скопированные линии после курсора; команда 5yyp "работает" но вероятно не делает того, что вам необходимо. Команда P делает тоже что и p, но помещает копию скопированного текста перед курсором; попробуйте эту последовательность - 5yyP.

Другие команды для вставки:

- y3w : Копирует три слова
- y$ : Копирует до конца текущей строки
- y1G : Копирует от текущей и до строки номер 1 (включая её)

## 9.6 Фильтрование текста

Команда фильтрования vi, запрашивает у пользователя имя команды UNIX (которая должна быть фильтром), затем пропускает выбранные строки сквозь фильтр,заменяя эти строки на строки обработанные фильтром. Возможность vi по фильтрованию произвольных фрагментов текста, через любой UNIX фильтр, добавляет гибкость и значительно расширяет ваши возможности по редактированию текста, без "дополнительной платы" в виде размера или производительности самого vi.

Несколько примеров помогут это проиллюстрировать. Создайте строку в вашем файле, содержащую слово who и ничего более. Поместите курсор на эту строку и нажмите !!. Эта команда похожа на dd,cc или yy но вместо удаления,изменения или копирования текущей строки,она фильтрует её. Когда вы нажимаете ! второй раз,курсор переходит на командную строку и в ней высвечивается подсказка !,приглашающая вас ввести название фильтра. В качестве имя фильтра введите sh и нажмите Enter. sh (Bourne shell) это фильтр! Он считывает команды со стандартного ввода, исполняет их и выдает результат исполнения на стандартный вывод. Команда who будет выполнена и в качестве результата выдаст список пользователей подключенных в данный момент к системе. В итоге вы получите этот список прямо в вашем файле, вместо слова who.

Попробуйте проделать то же самое с date. Создайте строку содержащую только слово date, затем поместите курсор на этой строке, введите !!sh и нажмите Enter. Строка будет заменена на вывод команды date

Поместите ваш курсор на какую-нибудь строку. Отсчитайте несколько строк, скажем 6. Введите 6!!sort и нажмите Enter. Оригинальные 6 строк будут заменены на вывод команды sort.

Команду фильтрования можно применять только на всей строке сразу, но не на отдельных словах или символах.

Некоторые другие команды фильтрования (здесь, < CR > означает - нажмите Enter):

- !/the < CR > sort < CR > : Сортирует текст от текущей строки до следующей строки содержащей the.
- !1Ggrep the < CR > :Уничтожает все строки от текущей до 1й (включая её), если они не содержат the.
- !Gawk '{print $1}' < CR > : Оставляет от всех строк (начиная с текущей и до конца файла) только первое слово.

## 9.7 Установка пометок

Вы можете выделить фрагмент текста, чтобы переместить,удалить,изменить,скопировать или отфильтровать его используя команду mc.

Например разместите курсор в центре какого-либо слова и нажмите ma. Это пометит символ под курсором меткой a.

Теперь переместите курсор с помеченного символа в другое место (используйте клавиши со стрелками или CTRL-u). Чтобы вернуться к помеченной строке нажмите 'a (одинарная скобка и a). Это переместит курсор на первый символ (не пробел) на помеченной строке.

Вновь уберите курсор с этой строки. Чтобы вернуться к помеченному символу нажмите `a (обратная одинарная скобка и a). Это поместит курсор поверх символа помеченного как a.

Установка меток обычно используется для его удаления,изменения,копирования или фильтрования. Например : переместите курсор на строку без метки и нажмите d'a (d,одинарная скобка,a). Эта команда удалит все начиная от текущей строки и заканчивая строкой с меткой.

Поместите курсор в центре какого-либо слова и нажмите mb чтобы установить метку b. Отодвиньте курсор на несколько строк и нажмите d`b (d,обратная одинарная скобка,b). Эта команда удалит все начиная от текущего положения курсора и заканчивая помеченным символом (включая его).

Другой пример : для сортировки вывода команды who, поставьте метку на первой строке вывода (ma), затем передвиньте курсор на последнюю строку и введите !'asort и нажмите Enter.

Если после того как вы перешли к метке вы захотите вернуться назад,нажмите '' чтобы вернуться к строке или '' чтобы вернуться к символу.

## 9.8 Назначение имени буферам

Когда вы удаляете,изменяете или копируете текст, оригинальный текст сохраняется (до следующей операции удаления, изменения или копирования) в безымянном буфере, из которого его можно извлечь с помощью p или P. Таким образом, в восстановить из безымянного буфера можно лишь недавно помещенный туда текст.

Если вы хотите удалить,изменить или скопировать несколько секций текста и при этом сохранить их все (вплоть до максимально возможных 26), вы можете задать имя буфера перед командой удаления или копирования.Имя буфера имеет следующий синтаксис "c (двойные кавычки и c).

Например введите "ayy чтобы скопировать текущую строку в буфер с именем a,затем перейдите на другую строку и нажмите "byy чтобы скопировать её в буфер b. Теперь перейдите в другое место в файле и нажмите "ap и "bp чтобы вставить содержимое буферов a и b.

Несколько других команд использующих буфер:

- "a6yy : Копирует шесть строк (текущую и пять следующих) в буфер a
- "bd1G : Удаляет все строки от текущей до первой (включая её),и размещает их в буфере b.
- "cy'c : Копирует текст начиная с текущей строки вплоть до строки отмеченной c и помещает скопиррованый фрагмент в буфер c. (отметки и буферы не связаны друг с другом и могут иметь одинаковые имена).

## 9.9 Замещение текста

Чтобы заместить один фрагмент текста другим используйте команду :s. Несколько примеров:

- :1,$s/the/THE/g Начиная с первой строки до последней (строки $), заместить все встреченные the на THE (g - означает глобальную замену)
- :'a,.s/.*/ha ha/ От строки помеченной как a до текущей (строки .), заменить любой текст на строку "ha ha".

## 9.10 Команды начинающиеся с двоеточия

Когда вы вводите двоеточие в командном режиме,курсор автоматически перемещается на командную строку и ждет ввода команды.

Некоторые примеры таких команд:

- :w Записывает содержимое буфера в файл без выхода из vi
- :w abc Записывает содержимое буфера в файл abc (если его нет он будет создан,иначе - перезаписан.) не выходя из vi
- :1,10w abc Записывает строки с 1 по 10 в файл abc
- :'a,$w abc Записывает строки от строки, помеченной как "a", до последней строки abc
- :e abc Загружает для редактирования файл abc, вместо текущего файла. Выдает ошибку если изменения в текущем файле не были сохранены.
- :e! abc Загружает для редактирования файл abc, не обращая внимание на несохраненные изменения в текущем файле.
- :e # Загружает для редактирования предшествующий файл (команда :e# следующий)
- :f abc Изменяет имя текущего буфера vi на abc
- :q Выходит из редактора, если нет несохраненных изменений
- :q! Выходит и уничтожает при этом все несохраненные изменения
- :r abc Считывает файл abc в текущий буфер vi, и размещает его за курсором.
- :!cmd Выполняет команду (who, sort, ls, etc.)

## 9.11 Установка опций

Существует множество опций которые влияют на работу vi. Вы можете отобразить все доступные опции с помощью команды :set all. Вы также можете использовать команду set для установки различных опций.

Например если вы хотите чтобы для строк в файле отображались их порядковые номера, используйте команду ":set number". Чтобы отключить отображение номеров строк введите ":set nonumber". Для указания большинства опций можно использовать аббревиатуры, например ":set nu" - включит нумерацию строк, а ":set nonu" отключит её.

Если вы установите ":set nomagic", то символы регулярных выражений имеющие специальное значение (период,астерик,квадратные скобки и т.д.) будут восприниматься как обычные. Используйте ":set magic" чтобы вернуть все назад.

Некоторые опции могут иметь параметры. Например ":set tabstop=4" заставит символ табуляции отображаться как четыре пробела, вместо обычных восьми.

Если вы хотите чтобы ваши опции сохранились и при следующем сеансе работы,вы можете поместить их в файл ".exrc",или установить переменную окружения EXINIT соответствующим образом.

Например если в качестве shell вы используете Bourne shell,вы можете разместить в вашем .profile такую строчку.

            EXINIT='set nomagic nu tabstop=4'; export EXINIT

Если вы используете C shell, необходимо разместить следующую строку в вашем .login файле.

            setenv EXINIT 'set nomagic nu tabstop=4'

## 9.12 Настройка клавиатурных комбинаций

Если вам приходиться выполнять серию простых команд опять и опять, то вы можете назначить этим командам определенную клавиатурую комбинацию (из неиспользуемых) с помощью команды :map.

Например следующая команда настраивает CTRL-А для передвижения курсора на 55 строк вперед, затем назад на самую последнюю пустую строку,на изменение этой командной строки на formfeed (CTRL-L) и три пустых строки. Т.е. CTRL-A отформатирует следующую страницу, без разделения параграфов между страницами.

Примечание: В этой строке каждый символ, который нужно нажимать совместно с CTRL показан как ^С, где С это большая буква. Например, СTRL-M показано как ^M. Также во время ввода вы не увидете ^V, т.к. СTRL-v нужно для того, чтобы подавить управляющее значение следующей за ним комбинации клавиш. Т.е. при вводе ^V^M вы увидете на экране лишь ^M(соотвествует Enter). ^[ соотвествует ESC.

            :map ^A  55+?^$^V^Mcc^V^L^V^M^V^M^V^M^V^[

## 9.13 Редактирование нескольких файлов

Вы можете редактировать несколько файлов, задав их имена как аргументы при запуске vi.

            vi croc fatherw  wknight

Для перемещения между файлами используются две команды:

- :n Перейти к следующему файлу в списке аргументов (вы должны сохранить изменения при помощи :w или vi выдаст сообщение о ошибке)
- :rew Перейти к редактированию первого файла в списке аргументов.

Команды :n и :rew, в каком то смысле неповоротливы, но они предоставляют несколько весьма полезных возможностей: содержимое поименованных буферов ("a,"b и т.д.) запоминается глобально, и вы сможете использовать :n и :rew команды совместно с p или P, чтобы копировать текст из одного файла в другой. Более того, запрос поиска, также запоминается глобально, и вы сможете искать одну строку в нескольких файлах.

Попробуйте провести следующий эксперимент: Выйдете из vi, запустите vi с croc и wknight в качестве аргументов:

            $ vi croc wknight

В файле croc, найдите

/the < CR >

Скопируйте это в буфер a:

"ayy

Перейдите к следующему файлу (мы не сделали никаких изменений в croc,поэтому это сработает):

:n < CR >

Проведем поиск еще раз, использовав в качестве аргумента поиска преведущий образец.

n

Поместите копию буфера a после текущей строки в wknight:

"ap

Перейдите на две строки вниз, и скопируйте текущую строку в буфер b:

jj"byy

Сохраним изменения в wknight

:w < CR >

Теперь вернемся к croc

:rew < CR >

Произведем поиск еще раз и разместит копию буфера b после найденной линии:

n"bp

Сохраним изменения и выйдем из vi

ZZ

## 9.14 Финальные замечания

Это пособии представляет некоторые возможности vi которые вы могли пропустить или не понять читая пособие по vi установленное в вашей системе.(на различных системах встречаются разные пособия).

Вы не станете экспертом по vi после чтения этого пособия,но вы ,по крайней мере, сможете оценить его возможности. Только время и тренировка могут сделать вас экспертом. Но универсальность и эффективность vi стоят этих усилий.

Вы можете решить что вы ненавидите vi. Но не забывайте что это единственный редактор доступный практически на любой UNIX системе, поэтому необходимо знать хотя бы самый минимум его команд.

Next Previous Contents