Оригінально стаття знаходиться за адресою: Vi - більш, ніж стандартний редактор, автор Дмитро Ковальов

Більш, ніж стандартний редактор

vi має два режими роботи:

  • перший, це той в якому він пищить;
  • і другий, в якому він не пищить.

З Юніксівського фольклору


В manpage до редактора ed в Юніксі традиційно писалося, що "ed є стандартним текстовим редактором Юнікса". І цим практично все сказано: ніхто не вправі чекати від "стандартного" текстового редактора чогось особливого - якихось там менюшок чи кнопочок "Start".

На відміну від ed, vi - не є вже "стандартним" в такому спартанському розумінні. Назва vi походить від VIsual . Тобто, це - повноекранний редактор. Але людину, яка своє комп'ютерне життя починала з Віндовсів, Макінтошів (або навіть і із Нортона Командера) vi може довести до сліз.

Тому виникає природнє запитання: "А нащо ж оці всі розмови про vi , якщо є Microsoft Word?" (Людина з більш принциповими поглядами на життя в цьому випадку спитала б: "У мене є emacs . Чого ти до мене чіпляєшся зі своїм vi ?")

Що ж - цей твір для людей закоханих у життя, для тих, кого не перестали ще хвилювати і звеселяти звичайні радощі земного життя, для тих, хто спроможен розуміти справжню поезію... Тобто, це пишеться для системних адміністраторів Юнікса. Ви не системний адміністратор? Досі? А чи ви хочете бути "ес-ей"? Це вже залежить від вас. Якщо у вас виникає якесь таке лоскотне відчуття під ложечкою від слів "Юнікс ґуру", читайте далі.

А коли трошки серйозніше... Є ситуації, де vi - ваш незамінний друг. В сучасному світі, бувають іще Юнікси без emacs 'ів, але уявити Юнікс без vi вже майже неможливо. Тим паче - без ed . І якщо вже так трапилось, що ваша система не має vi , а вам конче необхідно редагувати файл, то знаючи команди vi , ви з таким же самим успіхом можете користуватися ed 'ом.

Ви без проблем можете користуватися emacs 'ом для того, щоб писати свої CGI скрипти в Перлі чи Питоні. Але я певен, що серед сотні людей, яким потрібно змінити один рядок в /etc/passwd , навряд чи знайдеться навіть десяток бажаючих сидіти мовчки перед екраном, чекаючи, поки запуститься emacs . З цієї ж причини ніхто з цієї сотні ніколи в житті не буде користуватися Word'ом. (Ну, Ворд - це особливий випадок, і кожен з цієї-ж самої сотні, наведе мені ще десяток власних причин, чому він/вона не користується ні Вордом, ні Віндовс взагалі). Тому, зовсім непогано знати обидва редактори ( emacs і vi ) і користуватися кожним в залежності від потреб (продовжуючи тему додам, що зовсім немає нічого поганого в тому, щоб знати, як користуватися Word'ом. Але знати і користуватися - це зовсім різні речі).

vi (як, до речі і дуже багато чого в Юніксі) не належить до таких редакторів, які можна опанувати за кілька годин. Не належить він також і до тих редакторів, які можна зрозуміти до кінця на протязі кількох місяців. Це редактор, який опановується постійно в ході його використання, але навіть опанувавши деякі його можливості ви зможете ним користуватися і (можливо) полюбите його.

Про себе особисто додам, що деякі речі робляться набагато швидше у vi , ніж у emacs 'і, і коли мені треба зробити заміну чогось на щось (дуже часто із регулярними виразами) у величезному тексті, мені часто буває швидше записати файл на диск, відкрити його у vi , натиснути в ньому одну або дві клавіші і після цього повернутися в emacs .

Про те, що збиває з пантелику користувача vi

Почати сеанс роботи з редактором дуже просто. Практично будь-який текстовий редактор у Юніксі запускається командою

<назва_редактора> <назва_файлу>.

Не відрізняється цим від інших і vi.

Тож, щоб відкрити новий чи вже існуючий файл у vi, з командного рядка надрукуйте:

$ vi mytest.txt

При цьому відбувається те, що і збиває з пантелику будь-якого користувача редактора. Екран терміналу очищається, курсор переходить в лівий горішній кут екрану, а крайній лівий стовпчик екрану заповнюється тільдами (~). В нижньому рядку екрана друкується щось подібне на:

   "mytest.txt" <New File>

І, що саме головне, на будь-яку натиснуту клавішу vi відповідає або безглуздим бібіканням, або зовсім нічого не відповідає.

Саме тут і починається паніка. Не працює жодна з тих клавіш, які виручають в інших подібних ситуаціях: ні CTRL-C , ні CTRL-D.

Головна команда редактора

Що-ж, якщо ви вже відкрили файл так, як писалося в попередньому параграфі, не дочитавши до цього місця, зараз якраз саме час повернутися до читання. Не треба великого розуму, щоб почати редагувати файл. Але треба трохи подумати, коли прийшов час виходити з текстового редактора.

Кілька простих кроків, які ми даємо тут без пояснень (це так би мовити аксіома користування vi) - вихід з сеансу редагування з vi.

  1. Перш за все натисніть Esc. Це поверне вас з будь-якого режиму в режим, в якому vi схоче сприймати ваші команди.

  2. Далі введіть таку комбінацію клавіш:

    :wq ''Enter''

Отримавши це vi запише файл, який ви відкрили для редагування і вийде в командну оболонку. Як, мабуть, вже зрозумів здогадливий читач, w походить від write, а q - від quit. Це є насправді дві окремі команди, які просто об'єднані на одному рядку. Крім того vi може сприймати "довгі" версії команд - записані нормальною людською англійською. Тобто, команда наведена вгорі аналоґічна двом наступним варіантам:

  • Варіант 1 (дві окремі скорочені команди):

    :w  ''Enter'' 
    :q  ''Enter'' 
    
  • Варіант 2 (дві окремі команди, повна форма):

    :write ''Enter'' 
    :quit ''Enter'' 
    

Надалі я буду користуватися обома формами команд - повною та скороченою. Оскільки обидві форми абсолютно рівноправні, дія їх буде однаковою. А здогадуватися де саме коротка форма, а де повна, залишу як невеличку розминку для читача.

Що якщо вам не потрібно записувати зміни до файлу? Тоді не потрібно редактору казати щоб він записував файл. Але це просте твердження є неабиякою мукою для початківця.

Якщо ви на своє горе відкрили файл і зробили в ньому якісь зміни і тепер не знаєте як вийти з редактора не записуючи зміни (ви постирали якісь літери в полі паролів в файлі /etc/passwd і, звичайно ж, не пам'ятаєте які саме то були літери) і ви вже в котрий раз пробуєте надрукувати одну і ту ж команду: :qEnter. Але у відповідь на це vi відповідає тільки одним рядочком внизу екрану:

 ~
 No write since last change (use ! to override)

Бачите оте "use ! to override"? Це vi підказує вам, що для того щоб змусити його все-таки вийти з цього злополучного файлу і залишити на місці всі ті паролі, на нього треба крикнути. Але голосно! Тобто до команди "quit" треба ще додати знак оклику: " :quit! " (або :q! ). А про себе ще пошепки додати - "Та quit же ти, зараза!".

Цей же самий фокус спрацьовує, коли ви після важких і довгих замін раптом виявляєте, що відкрили файл, на який не маєте доступу на запис. В таких випадках спрацьовує :write! . Але, звичайно-ж, тільки в тих випадках, коли ви є власником файлу.

І останній варіант - вам треба змінити назву файлу. Скажімо, ви внесли зміни до файлу, а потім подумали, що зовсім не варто записувати його з тим самим іменем, яке він мав. В цьому випадку допоможе команда

:write <нова_назва>  ''Enter'' 

Режими роботи редактора vi

Складність початкового ознайомлення з vi полягає в тому, що він має різні режими роботи. Два основних режими, це - візуальний режим редагування тексту і командний режим. (Звичайно ж команди служать теж для редагування тексту, але звично виділяється окремий режим, в якому здійснюється "інтерактивне" редагування на відміну від, так би мовити "пакетного" редагування за допомогою виконання команд.)

Візуальний режим - це режим, в якому користувач пересувається по текстовому файлу і робить необхідні зміни в тексті. Це нагадує режим роботи будь-якого іншого текстового редактора (або навіть і текстового процесора - якщо комусь так подобається це така модне кілька років тому слово). У візуальному режимі роботи користувач має можливість проводити редагування тексту шляхом вставки, стирання чи заміни окремих літер, слів та текстових блоків.

Командний режим (або, як в деяких джерелах його називають "лінійним", чи скоріше навіть "по-рядковим" - linear) режим роботи, принципово відрізняється від візуального режиму тим, що в процесі роботи користувач рідко бачить на власні очі, що саме відбувається з текстом. Робота полягає у друкуванні команд на командному рядку, і в отриманні результатів. Це дуже нагадує процес роботи з командною оболонкою Юнікса.

Візуальний режим редагування

Оскільки візуальний режим роботи значно простіший для початкового ознайомлення, саме з нього ми й почнемо.

Для переходу з режиму лінійно редагування в візуальний режим існують кілька способів. Далі ми будемо розглядати деякі з них по черзі. Але відразу ж запам'ятаємо, що для виходу з режиму вводу існує всього один спосіб - натистути та відпустити Esc . В командному режимі клавіша Esc нічого не означає, тому працюючи в vi виробляється своєрідна звичка - перш, ніж виконувати будь-яку команду натискати Esc (навіть кілька разів) - згубна звичка для тих, хто працює в emacs'і.

Деякі версії vi (це стосується практично всіх версій vi , які розповсюджуються з Лінаксом) друкують в нижньому рядку екрану підказку, коли вони знаходяться в режимі вставки тексту. Ця підказка - це рядок

 "-- INSERT -- "

внизу екрану. Але навіть на це розраховувати не доводиться, бо таку підказку видають далеко не всі vi . Тому основне правило при роботі з vi було і залишається - завжди пам'ятати в якому режимі ви знаходитесь, а якщо не певні - натискайте зайвий раз Esc і повертайтеся в візуальний режим.

Вставка тексту

Перейти в режим вставки тексту можна кількома способами. Ось кілька з них (всі літери команд - англійські літери, малі літери та великі мають різні функції в vi ):

i - починає вставку тексту ліворуч від курсора;
a - починає вставку тексту праворуч від курсора;
A - додає текст до кінця рядка.

Просте пересування по тексту

vi має надзвичайно багато способів пересуватися по тексту, але для початку нам вистачить самих основних - перехід праворуч-ліворуч на один символ та вгору-вниз на один рядок.

Знову ж таки, в залежності від вашої удачі, ваш vi може або підтримувати або не підтримувати пересування по тексту за допомогою клавіш із стрілками. Це може залежати не тільки від версії Юнікса, але навіть від терміналу, на якому ви працюєте. Наприклад, при роботі в X Window в SunOS або Solaris можна користуватися стрілками, а при користуванні vi на текстовій консолі в цих же системах вони не працюють.

Якщо стрілки працюють, то тут нема про що більше говорити - просто натискайте стрілку вгору, щоб перейти на попередній рядок, ліворуч - щоб перейти ліворуч і т.д. Якщо ж ні, то вам потрібно буде користуватися алфавітними клавішами для цього. Для пересування по екрану використовуються такі клавіші:

h - ліворуч;
j - вниз;
k - вгору;
l - праворуч.

Намагатися запам'ятати ці клавіші зовсім не потрібно (і взагалі - марна справа). На клавіатурі вони всі знаходяться поруч - в одному ряду. Тому, якщо ви покладете п'ястки, так, що вказівний палець припадає на h , то будете мати керування всім своїм редактором на пальцях однієї руки (правої, якщо ви цього ще не зрозуміли). Вказівний палець та мізинець рухають курсор ліворуч та праворуч відповідно. А середній та безім'янний - вниз та вгору.

Крім цих команд для пересування по тексту спрацьовують також такі клавіші:

Enter - вниз;
SPACE - праворуч;
Del   - ліворуч.

Ще до цього потрібно додати, що такий рух можливий тільки там, де вже є вставлені рядки. Тобто, в нашому прикладі ви не дуже то і порухаєтесь. Перш, ніж тиснути всі чотири клавіші по черзі з нульовим результатом, треба ввести хоча б кілька рядків у вікні vi .

Проста заміна тексту

Для початку розглянемо найпростіші способи заміни тексту - заміна одного символа та заміна кількох символів.

Щоб замінити один символ, пересуньте курсор так, щоб він знаходився під символом, що ви його хочете замінити. Натисніть r і після цього той символ, на який ви хочете змінити.

Щоб змінити підряд кілька символів пересуньте курсор так, щоб він знаходився під першою із літер, які ви збираєтесь змінити і натисніть R . Після цього починайте друкувати новий текст. Новий текст буде змінювати старий в ході того, як ви будете друкувати. В кінці заміни натисніть Esc для того, щоб вийти з режиму заміни.

Тільки що поданих команд взагалі-то кажучи достатньо для мінімального користування vi , і багато чиї знання обмежуються саме цим необхідним мінімумом. Як кажуть знавці - цей редактор вивчити досконало просто неможливо, завжди буде щось таке, що залишається невідомим.

Складніші методи пересування по тексту та команди заміни тексту

Пересуватися туди-сюди по одній літері чи рядку досить велика морока, така ж сама морока і натискати r кожного разу, коли вам потрібно замінити одну єдину літеру.

Тож тут далі (в досить стисненій формі) команди для пересування та заміни:

e - перейти в кінець слова;
b - перейти на початок слова;
E - перейти в кінець слова;
B - перейти на початок слова;
^ - перейти на початок рядка;   
$ - перейти в кінець рядка.

cw - замінити слово (в кінці вводу слова натисніть  ''Esc'' );
cW - замінити слово (в кінці вводу слова натисніть  ''Esc'' );
cl - замінити літеру

А також операції для стирання літер та блоків тексту:

x - стерти літеру в позиції (праворуч від) курсора;
X - стерти літеру ліворуч від курсора;
dw - стерти слово (від позиції курсора праворуч до кінця
     слова);
dW - стерти слово (від позиції курсора праворуч до кінця
     слова);
dd - стерти рядок, на якому стоїть курсор (повністю, не
     залежно від позиції курсора в цьому рядку);
D - стерти все, починаючи від курсора до кінця рядка;
s - стирає літеру в позиції курсора і переводить в режим вводу
    тексту в цій же позиції (вихід з режиму вводу -  ''Esc'' ).

В кількох випадках вгорі приведені команди, які, судячи з опису ніби-то роблять одне і те, але відрізняються тим, що в одному випадку використовуються малі літери, а в інших - великі. Різниця в цих командах полягає в тому, як трактується "слово" в цих командах.

В командах з малими літерами (e, b, cw, dw) під словом розуміється все, що складається з літер. "А з чого ж ще може складатися слово?" Ось про це саме мова йде в розмові про команди, що складаються з великих літер. Під словом в цих командах розуміється все, що складається з літер (алфавітно-цифрових символів) та розділових знаків.

Продемонструємо це на таких прикладах:

   +-------------------------------------------------
   | Hei, malyi, skazhy malomu-khai malyi malomu skazhe
   |                    ^
    ''Положення курсора до виконання команди'' 

   +-------------------------------------------------
   | Hei, malyi, skazhy malomu-khai malyi malomu skazhe
   |                         ^
    ''Положення курсора після виконання команди''  :e

   +-------------------------------------------------
   | Hei, malyi, skazhy malomu-khai malyi malomu skazhe
   |                              ^
    ''Положення курсора після виконання команди''  :E

Теж саме стосується і інших команд, які відрізняються тільки великими та малими літерами (крім команд x та X). Так, команда :dw в попередньому прикладі зітре одне слово - "malomu", в той час як команда :dW зітре два слова з'єднані дефісом - "malomu-khai".

Багаторазове виконання команд

Дуже часто буває потрібно виконувати одну і ту ж команду по кілька разів. Наприклад, стерти три підряд слова чи п'ять наступних рядків. Чи, може, перейти ліворуч на 20 літер.

Є дуже приємна новина - редактор дозволяє виконувати команди пачками. По кілька команд за раз. І робити це у vi дуже просто, Але для початку ми розглянемо найпростіший варіант. Скажімо, ви виконали якусь команду, а потім подумали собі: "А чи не виконати мені цю команду ще раз? Дуже вже вона мені сподобалась!" І ви вирішуєте: "Виконаю!" І ... натискаєте ... крапку(!?) Так, саме крапку. Крапка у vi означає повтор тільки-що виконаної команди.

Наприклад:

   +-------------------------------------------------
   | Hei, malyi, skazhy malomu-khai malyi malomu skazhe
   |                    ^
    ''Положення курсора до виконання команди'' 

   +-------------------------------------------------
   | Hei, malyi, skazhy -khai malyi malomu skazhe
   |                    ^
    ''Положення курсора після виконання команди''  :dw

   +-------------------------------------------------
   | Hei, malyi, skazhy malyi malomu skazhe
   |                    ^
    ''Положення курсора після виконання команди''  "."   ''Увага!!! Тут є крапка! '' 

   +-------------------------------------------------
   | Hei, malyi, skazhy malomu skazhe
   |                    ^
    ''... і ще після однієї''  "."   '' ... і тут теж ...'' 

Можлива також інша форма команди. Практично всі команди vi можуть сприймати числовий параметр, який ставиться перед командою. Цей числовий параметр означає кількість повторів даної команди. Тоді всі наведені вище команди перетворюються на щось таке:

Ne - перейти в кінець слова (N разів);
Nb - перейти на початок слова (N разів);
NE - перейти в кінець слова (N разів);
NB - перейти на початок слова (N разів);

Ncw - замінити слово (N разів);
NcW - замінити слово (N разів);
Ncl - замінити літеру

Nx - стерти літеру в позиції (праворуч від) курсора (N разів);
NX - стерти літеру ліворуч від курсора (N разів);
Ndw - стерти слово (від позиції курсора праворуч до кінця
     слова) (N разів);
NdW - стерти слово (від позиції курсора праворуч до кінця
     слова) (N разів);
Ndd - стерти рядок, на якому стоїть курсор (повністю, не
     залежно від позиції курсора в цьому рядку) (N разів);
Ns - стирає літеру в позиції курсора і переводить в режим вводу
    тексту в цій же позиції (N разів - тобто стирає N літер і
    потім переводить в режим вводу);
Nh - ліворуч (N разів);
Nj - вниз (N разів);
Nk - вгору (N разів);
Nl - праворуч (N разів).

В усіх вище наведених командах N - це будь-яке число надруковане на клавіатурі. Коротше кажучи, щоб перейти на 5 рядків вниз по тексту наберіть на клавіатурі 5j , щоб стерти 5 рядків (вниз від того місця, де ви знаходитесь) - наберіть 5dd , і т.д.

Це також стосується команд вводу тексту. Якщо вам потрібно вставити 20 однакових рядків в текстовий файл, проробіть таке: натисніть 20i , після цього вводьте ваш текстовий рядок, закінчіть ввід натисканням _ Enter _ і врешті-решт закінчіть все це натисканням _ Esc. _ vi сприймає все це (що починається з i і закінчується _ Esc _ ) як одну команду і повторить її 20 разів.

Приклад:
   +-------------------------------------------------
   | 
   | 

   3iCei ryadok povtoryt'sya 3 razy ''Enter Esc'' 

   +-------------------------------------------------
   | Cei ryadok povtoryt'sya 3 razy
   | Cei ryadok povtoryt'sya 3 razy
   | Cei ryadok povtoryt'sya 3 razy
   | 

Якщо тільки-що наведений приклад проробити без _ Enter _ , то буде таке:

Приклад:
   +-------------------------------------------------
   | 
   | 

   3iCei ryadok povtoryt'sya 3 razy ''Esc'' 

   +-------------------------------------------------
   | Cei ryadok povtoryt'sya 3 razy Cei ryadok povtoryt'sya 3 razy Cei ryadok povtoryt'sya 3 razy 
   | 
   | 
   | 

І на закінчення цієї теми: кілька команд для пересування по тексту цілими екранами, та більшими шматками - на початок файлу та в кінець файлу.

   ''Ctrl'' -f - перейти на один повний екран вперед;
   ''Ctrl'' -b - перейти на один повний екран назад;
   :1         - перейти на перший рядок файлу;
   :$         - перейти в кінець файлу.

Natalya and Dmytro Kovalev
Пишіть нам за адресою:kov@tokyo.email.ne.jp
Домашня сторінка: http://www.asahi-net.or.jp/~as9d-kvlv
Thu Nov 11 15:45:30 JST 1999