2004 г
Основы операционной системы UNIX
Copyleft (no c) - 1996-2004
В. Кравчук,
OpenXS Initiative, идея, составление, перевод, примеры
Назад Оглавление Вперёд
Средства обработки текста
Редактирование и вообще обработка текстов - одна из основных операций, выполняемых
на компьютерах. Стандартные средства редактирования в ОС UNIX появились давно и
ориентированы на простейшие текстовые терминалы. К таким средствам можно отнести
строковый редактор ed
и экранный редактор vi.
При первом знакомстве они могут показаться сложными и явно устаревшими с точки зрения
"дружественности", однако в мире UNIX хорошо не то, что является самым новым и "красивым",
а, скорее, то, что используется давно, многими людьми и есть в любой версии. Это в
полной мере относится к стандартным средствам обработки текстов.
Эффективность обработки текста определяется эффективностью поиска необходимых
фрагментов. Для задания образцов поиска в ОС UNIX используется ряд метасимволов
регулярных выражений, впервые появившихся в редакторе ed и представленных в табл.
19.
Таблица 19. Метасимволы регулярных выражений
Метасимвол |
Описание |
c |
Любой конкретный символ задает совпадение с таким же символом |
\c |
Отменяет специальный смысл символа c |
^ |
Соответствует началу строки, когда ^ начинает образец |
$ |
Соответствует концу строки, когда $ заканчивает образец |
. |
Совпадает с любым одиночным символом |
[...] |
Соответствует одному любому символу в ...; допустимы диапазоны
типа a-z |
[^...] |
Соответствует любому одиночному символу, не входящему в ...;
допустимы диапазоны |
r* |
Соответствует нулевому или более числу вхождений r, где r - символ
или [...] |
& |
Используется только в правой части команд замены (s); вставляет
фрагмент, совпавший с образцом |
\(...\) |
Помечает регулярное выражение; найденные строки доступны как \1,
\2 и т.д. до \9 в левой и правой частях соответствующей команды
замены s, а также в шаблонах поиска сразу после закрытия
соответствующей круглой скобки. |
Простые примеры регулярных выражений и задаваемых ими шаблонов поиска
представлены в табл. 20.
Таблица 20. Примеры использования регулярных выражений
Образец |
Соответствие |
/^$/ |
пустая строка, т.е. только конец строки |
/./ |
непустая строка, по крайней мере один символ |
/^/ |
все строки |
/thing/ |
thing где-либо в строке |
/^thing/ |
thing в начале строки |
/thing$/ |
thing в конце строки |
/^thing$/ |
строка, состоящая лишь из thing |
/thing.$/ |
thing плюс любой символ в конце строки |
/\/thing\// |
/thing/ где-либо в строке |
/[tT]hing/ |
thing или Thing где-либо в строке |
/thing[0-9]/ |
thing, за которой идет одна цифра |
/thing[^0-9]/ |
thing, за которой идет не цифра |
/thing1.*thing2/ |
thing1, затем любая строка, затем thing2 |
/^thing1.*thing2$/ |
thing1 в начале и thing2 в конце |
Чтобы манипулировать не только целыми фрагментами, выбираемыми регулярными
выражениями, но и их частями, используются помеченные регулярные выражения: если
конструкция \(...\) появляется в регулярном выражении, то часть соответствующего ей
фрагмента доступна как \1. Допускается использование до девяти помеченных
выражений, на которые ссылаются \1, \2 и т.д.
Вот ряд примеров использования помеченных регулярных выражений:
s/\(...\)\(.*\)/\2\1/ |
Поместить 3 первых символа в конец строки |
/\(..*\)\1/ |
Найти строки, содержащие повторяющиеся смежные цепочки символов |
s/^\(..*\)\.\(..*\)/\1.\
\2/ |
Перенести остаток строки после первой точки на следующую строку |
Программы
семейства grep
осуществляют поиск шаблона (задаваемого на языке регулярных выражений)
в указанных файлах или во входном потоке и (обычно) выдают
соответствующие шаблону строки в выходной поток. В это семейство входят три
программы, grep, egrep и fgrep, отличающиеся алгоритмами (а, значит,
скоростью работы и используемыми ресурсами системы) и, частично, возможностями при задании
шаблонов.
Вызов программы grep
Вызов команды grep имеет следующий синтаксис:
-
grep [опции] [регулярное_выражение] [файл ...]
Команда ищет строки, задаваемые шаблоном в виде ограниченного регулярного
выражения (используют подмножество допустимых алфавитно-цифровых и специальных
символов), аналогичного используемым в ed, в указанных файлах или во входном потоке.
Возможные опции приведены в табл. 21.
Таблица 21. Опции командной строки grep
Опция |
Назначение |
-b |
Перед каждой строкой выдавать номер блока, в котором она найдена.
Это может пригодиться при определении номера блока по контексту |
-c |
Выдавать только количество строк, соответствующих шаблону |
-i |
Игнорировать разницу между прописными и строчными буквами |
-h |
Предотвращает выдачу имени файла перед совпавшей строкой.
Используется при многофайловом поиске. |
-l |
Выдавать имена файлов, содержащих совпавшие строки, один раз,
разделяя их переводом строки. Не повторяет имена файлов, если
шаблон найден более одного раза. |
-n |
Предваряет каждую строку ее порядковым номером (первая строка имеет номер 1) |
-s |
Подавляет выдачу сообщений об ошибках, связанных с не
существованием файлов или недоступностью для чтения |
-v |
Выдает все строки, кроме тех, что содержат шаблон |
-e se |
Ищет специальное выражение se (полное регулярное выражение,
начинающееся с -) |
-f файл |
Берет список полных регулярных выражений из файла |
Будьте внимательны при использовании символов $, *,
[, ^, |, (, ) и \ в шаблоне, так как
они также имеют значение для командного интерпретатора. Лучше заключать искомый
шаблон в апострофы: '...'.
Статус выхода равен 0, если найдены совпадающие строки, 1 - если строки не найдены и 2
если имеется синтаксическая ошибка или недоступные файлы (даже если совпадения
найдены).
Рассмотрим простые примеры:
[kravchuk@arturo 17:30:29 /]$ echo abc abc | grep '\([abc][abc]*\) \1'
abc abc
[kravchuk@arturo 17:31:13 /]$ echo abc abc | grep 'c a'
abc abc
[kravchuk@arturo 17:31:22 /]$ echo abc abc | grep '^c a'
[kravchuk@arturo 17:31:26 /]$ cd $INFORMIXDIR/etc
[kravchuk@arturo 17:31:45 /usr/inf.731/etc]$ grep -n $INFORMIXDIR
^C
[kravchuk@arturo 17:32:03 /usr/inf.731/etc]$ grep -n tmp *.sh
beta_evidence.sh:306: DUMPDIR=/tmp
bldutil.sh:40:# remove tmp salvage_file
bldutil.sh:55: RESFILE=/tmp/bldutil.$$
evidence.sh:302: DUMPDIR=/tmp
logevent.sh:46:TMPFILE=${TMPDIR:-/tmp}/$PROG.`date +%y-%m-%d-%H%M-%S`
vi (vedit) - экранно-ориентированный текстовый редактор. Он позволяет видеть
одновременно целую страницу текста, перемещаться по нему курсором и
непосредственно видеть вносимые изменения.
Редактор vi
является наследником строкового редактора
ex, который,
в свою очередь, является расширением базового текстового редактора
ed.
Тем самым, обеспечивается преемственность средств редактирования и
использование эффективного механизма поиска и замены на базе регулярных выражений.
Вызов
Для вызова редактора vi в простейшем случае используется следующий синтаксис:
-
vi [+строка] [ файл ]
В результате, указанный файл открывается в окне редактора. Если файл не указан,
редактируется первоначально пустой буфер (т.е. новый файл, имя которого первоначально
не задано).
Строку, на которой открывается файл, можно задавать следующим образом:
+номер |
Строка с указанным номером |
+ |
Последняя строка файла |
+/re |
Строка, соответствующая указанному регулярному выражению re |
Указанная строка будет находиться в центре экрана (если только файл не меньше, чем
размер экрана) и в ее начале будет установлен курсор.
Режимы работы
Редактор vi поддерживает несколько режимов работы:
Командный режим |
Нормальный и начальный режим. По завершении других
режимов происходит возврат в командный режим. Для
форсированного перехода в этот режим используется клавиша
Esc |
Режим ввода |
В режим ввода входят при задании одной из следующих
команд: a A i I o O c C s S R. При этом может набираться
произвольный текст. Из этого режима выходят либо по Esc,
либо он автоматически прерывается редактором. При этом
обычно подается звуковой сигнал. |
Режим последней строки |
Чтение ввода для команды : / ? или !; прекращается нажатием
клавиши Enter. |
Основные команды
Основные команды редактора vi представлены в табл. 22.
Таблица 22. Сводка основных команд редактора vi
Перемещение курсора |
H (Ctrl-h) |
курсор влево |
J (Ctrl-n) |
курсор вниз |
K (Ctrl-p) |
курсор вверх |
L (Space) |
курсор право |
Ctrl-u |
Переход вверх на половину экрана |
Ctrl-d |
Переход вниз на половину экрана |
Ctrl-f |
На страницу вперед (PageDn) |
Ctrl-b |
На страницу назад (PageUp) |
0 |
Переход в начало текущей строки |
$ |
Переход в конец текущей строки |
nG |
Переход на строку с номером n |
Добавление текста |
a |
Добавить текст после курсора |
A |
Добавить текст в конце текущей строки |
i |
Вставить текст перед курсором |
I |
Вставить текст в начале текущей строки |
o |
Образовать новую строку под текущей |
O |
Образовать новую строку над текущей |
Изменение текста |
~ |
Изменить регистр символа над курсором |
r |
Замена одного символа |
R |
Замена символов |
Удаление текста |
x |
Удаление символа |
dd |
Удаление строки |
Ndd |
Удаление N строк |
Поиск и замена |
/str |
Поиск строки str вперед. str может быть регулярным выражением |
?/str |
Поиск строки str назад |
n |
Повторить поиск в том же направлении |
N |
Повторить поиск в обратном направлении |
:[range]s/old/new/[g] |
Заменить old на new в указанном диапазоне строк
range. new и old могут быть регулярными
выражениями, а range задается аналогично
диапазону строк в редакторе
ed.
Суффикс g означает заменить во всем файле. |
Копирование текста |
yy |
Копирование строки в целом |
Nyy |
Копирование N строк |
p |
Вставить из буфера после (курсора, текущей строки) |
P |
Вставить из буфера перед (курсором, текущей строкой) |
Выход из редактора |
:wq ENTER |
Запись и выход. Записать текст из буфера в файл и выйти из редактора. |
:x ENTER |
Условная запись и выход. Записать текст из буфера
только при наличии изменений и выйти из редактора. |
:q! ENTER |
Закончить редактирование без записи изменений. |
Другие команды |
! |
Выполнить одну команду интерпретатора |
. |
Повторить последнюю команду |
u |
Отменить действие последней команды |
J |
Соединить строки |
Ctrl-G |
Показать номер текущей строки |
Курсор можно перемещать и клавишами перемещения курсора или клавишами PageUp,
PageDn, но эти возможности, в отличие от описанных в таблице, поддерживаются не на
всех терминалах.
Назад Оглавление Вперёд