Книга: UNIX — универсальная среда программирования
Приложение 1 Краткое описание редактора
Разделы на этой странице:
- Основные сведения
- Временная передача управления shell с помощью '!'
- Печать
- Образцы
- Добавление, замена, исключение, вставка
- Подстановка, аннулирование
- Метасимволы и регулярные выражения
- Глобальные команды
- Перемещение и копирование строк
- Метки и номера строк
- Объединение, расщепление и реорганизация строк
- Команды, работающие с файлами
- Шифрование
- Сводка команд
- Упражнение
Приложение 1
Краткое описание редактора
Стандартный текстовый редактор UNIX создан К. Томпсоном в начале 70-х годов для вычислительной среды на малых машинах (первая система UNIX ограничивала предельный размер программ пользователя до 8К байт) с терминалами "твердой копии", работавшими при очень низких скоростях (10-15 символов в секунду). Этот редактор написан на базе более ранней версии qed
, которая была в то время популярна.
С развитием технологии ed
постигла та же судьба. Почти наверняка вы найдете в своей системе другие редакторы с интересными свойствами, в частности с возможностью "визуального", или "экранного", редактирования, при котором на экране терминала отражаются все вносимые вами коррективы.
Почему же тогда мы тратим время на, казалось бы, устаревшую программу? Дело в том, что ed
выполняет некоторые операции весьма успешно, несмотря на свой возраст. Эта программа есть на всех установках UNIX, и вы всегда найдете ее при переходе с одной системы на другую. Она работает хорошо и с низкоскоростными телефонными линиями, и с любыми терминалами. Кроме того, ed
легко запускать из командного файла, в то время как большинство экранных редакторов управляются с терминала и не могут должным образом получить входной поток из файла.
Редактор ed
предоставляет регулярные выражения для поиска по образцу. Регулярные выражения, на которых основан ed
, присутствуют во всех частях системы: grep
и sed
применяют почти такие же, a egrep
, awk
, lex
расширяют их. Shell использует для сравнения имен файлов иной синтаксис, но те же самые идеи. Некоторые экранные редакторы имеют "строчный режим", который предусматривает обращение к регулярным выражениям ed.
И, наконец, ed
обладает высоким быстродействием. Вполне возможно вызвать ed
, заменить в файле одну строку, записать новую версию и вернуться из него, причем все это происходит быстрее, чем один только запуск большого и более сложного экранного редактора.
Основные сведения
Программа ed
редактирует один файл за один раз. Она работает с копией файла. Чтобы внести исправления в первоначальный файл, вы должны дать явную команду. Редактор предоставляет команды для манипуляций с последовательными строками или строками, соответствующими образцу, а также команды для внесения в строки изменений.
Каждая команда ed
представляет собой символ (обычно букву). Большинству команд может предшествовать один или два номера строки, которые указывают, на какую строку или строки должна воздействовать команда: в противном случае подразумевается номер, принятый по умолчанию. Номер строки можно специфицировать абсолютной позицией в файле (1, 2 ...), символами $
для последней строки и ".
" для текущей, процедурой поиска по образцу, использующей регулярные выражения, и их аддитивными комбинациями.
Рассмотрим, как с помощью ed
можно создавать файлы, используя стихи Де Моргана из первой главы.
$ ed poem
Предупреждение: файл poem не существует
? poem
а
Начать добавление строк
Great fleas have little fleas
Печатаем '.' чтобы закончить ввод
upon their backs to bite 'em,
And little fleas have lesser fleas,
and so ad infinitum.
.
w poem
Пишем строки в файл poem
121
ed сообщает, что записан 121 символ
q
Выход
Команда а
добавляет или присоединяет строки. Режим добавления заканчивается строкой, состоящей из одной точки. Из-за отсутствия индикации режима, в котором вы работаете, возможны две распространенные ошибки: ввод текста без команды а
и ввод команды до ввода '.
'.
Редактор ed
никогда не будет писать ваш текст в файл автоматически; вы должны задать это с помощью команды w
. Однако, если вы пытаетесь закончить редактирование без записи ваших изменений, ed
выдает '?
' как предупреждение. Есть другая команда q
, позволяющая завершить работу независимо от внесения исправлений.
$ ed poem
Файл существует и имеет 121 символ
121
а
Добавить еще строки в его конец
And the great fleas themselfs, in turn,
Печатаем '.' для завершения
have greater fleas to go on;
While these again have greater still,
and greater still, and so on.
.
q
Пытаемся выйти
?
Предупреждение: не было записи
w
Нет имени файла; подразумевается poem
263
Теперь можно выходить
q
$ wc poem
Проверьте для уверенности
8 46 263 poem
$
Временная передача управления shell
с помощью '!
'
Если вы запустили ed
, то можете временно выйти из него, чтобы запустить другую команду shell
. В этом случае нет необходимости прекращать работу достаточно ввести команду ed
'!
'.
$ ed poem
Запуск wc без выхода из ed
! wc poem
8 46 263 poem
Вернулись из команды
!
q
Выход без w годится: не было исправлений
$
Печать
Строки файла нумеруются как 1, 2 … Вы можете печатать n-ю строку, дав команду np или просто номер n, и строки с m
по n, используя m,np
. "Номером строки" $
обозначается последняя строка, так что строки можно не считать.
1 |
Печатать первую строку; 1р то же самое |
$ |
Печатать последнюю строку; $p то же самое |
1,$p |
Печатать строки с первой по последнюю |
Печатать файл по одной строке проще всего; нажимая клавишу RETURN
, вы можете вернуться на одну строку назад с помощью '-
'. Можно комбинировать номера строк с '+
' и '-
'.
$-2,$p |
Печатать последние три строки |
1,2+3p |
Печатать строки с первой по пятую |
Однако нельзя печатать после конца файла или в обратном порядке; команды типа $,$+1p
и $,1p
считаются незаконными.
Команда list 1
выводит текст в формате с видимыми символами. Это удобно при поиске в файлах управляющих символов, при различении пробелов, табуляции и т.п. (см. vis
в гл. 7).
Образцы
Как только размер начинает превышать две строки, становится неудобным печатать его весь целиком, чтобы отыскать нужную строку. Редактор ed
предлагает способ поиска строк, совпадающих с некоторым образцом, шаблоном: /pattern/
обнаруживает очередное вхождение pattern
.
$ ed poem 263
Ищет очередную строку, содержащую flea
/flea/
Great fleas have little fleas
Ищет еще одну
/flea/
And little fleas have lesser fleas,
Ищет следующую по тому же образцу
//
And the great fleas themselves, in turn,
Поиск в обратном направлении по тому же образцу
??
And little fleas have lesser fleas,
Редактор запоминает образец, применявшийся вами в последний раз, так что можно повторить поиск просто с помощью //
. Для поиска в обратном направлении воспользуйтесь ?pattern?
и ??
.
Поиск с помощью /.../
и ?...?
циклический, т.е. продолжается в обратном направлении после достижения одного из концов текста:
$p
Печатать последнюю строку ('p' необязательна)
and greater still, and so on.
Следующее flea вблизи начала
/flea/
Great fleas have little fleas
От начала идет в обратном направлении
??
have greater fleas to go on;
Результатом поиска по образцу типа /flea/
является номер строки, например 1 или $
, который может использоваться в том же контексте, что и такие номера:
1,/flea/p |
Печатать от единицы до следующего flea |
?flea?+1,$p |
Печатать от предыдущего flea + 1 до конца |
Текущая редактируемая строка. Редактор ed
отслеживает последнюю строку, с которой имели дело: печатали или вводили текст, читали из файла. Это текущая строка с именем '.
'. Каждая команда определенным образом влияет на текущую строку, обычно настраивая ее на ту, с которой она последний раз работала. Вы можете использовать текущую строку так же, как $
или номер строки типа 1:
$ ed poem
Печатает текущую строку; после чтения файла
263
.
это то же, что $
and greater still, and so on.
Печатает предыдущую строку и еще одну
.-1,.p
While these again have greater still,
and greater still, and so on.
Выражения для номера строки могут быть сокращены:
Сокращение | Эквивалент | Сокращение | Эквивалент |
---|---|---|---|
-1 |
.-1 |
+ |
.+1 |
-- или -2 |
.-2 |
++ или +2 |
.+2 |
-n |
.-n |
+n |
.+n |
$- |
$-1 |
.3 |
.+3 |
Добавление, замена, исключение, вставка
Команда а
(добавить) добавляет строки после определенной строки, команда d
(удалить) вычеркивает строки, команда i
(вставить) вставляет строки перед определенной строкой, команда с
(заменить) заменяет строки, действуя как комбинация команд "удалить" и "вставить".
na |
Добавить текст после строки n |
ni |
Вставить текст перед строкой n |
m,nd |
Удалить строки с m по n |
m,nc |
Заменить строки с m по n |
Если номера строк не указаны, используется текущая строка. Новый текст для команд а
, с
и i
оканчивается строкой '.
'; точка, введенная в последней строке, оставляется. Текущая строка настраивается на следующую строку после последней удаленной, за исключением случая, когда удалена последняя строка, т.е. $
.
0а |
Добавить текст в начало (то же, что 1i ) |
dp |
Удалить текущую строку, печатать следующую (или последнюю, если $ ) |
.,$dp |
Удалить отсюда до конца, печатать новую последнюю |
1,$d |
Удалить все |
?pat?,.-1d |
Удалить от предыдущей, совпадающей с 'pat ' до той, что перед текущей |
$dp |
Удалить последнюю строку, печатать новую последнюю |
$c |
Заменить последнюю строку ($а добавляет после последней строки) |
1,$c |
Заменить все строки |
Подстановка, аннулирование
Нет необходимости перепечатывать целую строку, если в ней нужно заменить лишь несколько символов. Команда подстановки s заменяет одну последовательность символов другой:
s/old/new/ |
Заменить первую old на new в текущей строке |
s/old/new/p |
Заменить первую old на new и печатать строку |
s/old/new/g |
Заменить каждую old на new в текущей строке |
s/old/new/gp |
Заменить каждую old на new и печатать строку |
Заменяется только самое левое вхождение образца в строке, если не написана буква 'g
'. Команда s выводит измененную строку только в том случае, когда она оканчивается буквой 'p'. Фактически большинство команд ed
выполняет свою работу "молча", но почти любая команда может быть завершена буквой p для вывода результата.
Если подстановкой вы не добились того, что хотели, с помощью команды u (аннулировать) можно уничтожить последнюю подстановку. Текущая строка должна быть настроена на преобразованную строку:
u |
Аннулировать последнюю сделанную подстановку |
up |
Аннулировать последнюю подстановку и напечатать |
Как вам уже известно, командам p и d
могут предшествовать один или два номера, указывающие строки, на которые нужно воздействовать. Этот же принцип используется и для команды s.
/old/s/old/new/ |
Найти следующую old ; заменить на new |
/old/s//new |
Найти следующую old ; заменить на new (образец запоминается) |
1 ,$s/old/new/p |
Заменить первую old на new в каждой строке; печатать последнюю измененную строку |
1,$s/old/new/gp |
Заменить каждую old на new в каждой строке; печатать последнюю измененную строку |
Отметим, что 1,$s
вызывает команду для обработки каждой строки, но это означает лишь самое левое вхождение образца в каждой строке; нужна заключительная команда 'g
', чтобы заместить все вхождения во всех строках. Кроме того, p выдает только последнюю измененную строку. Для вывода всех измененных строк необходима глобальная команда, которую мы вскоре рассмотрим.
Символ &
означает сокращение; оказавшись где либо справа от команды s, он заменяется образцом из левой части:
s/big/very &/ |
Заменить big на very big |
s/big/& &/ |
Заменить big на big big |
s/.*/(&)/ |
Взять в скобки целую строку (см. .* ниже) |
s/and/&/ |
Заменить and на & ( отключает специальное значение символа) |
Метасимволы и регулярные выражения
Как и символы *
, >
, :
, имеющие специальный смысл в shell
, некоторые символы имеют специальный смысл для ed
, если они появляются в образце для поиска или в левой части команды s. Эти символы называют метасимволами, а использующие их образцы регулярными выражениями. В табл. П.1.1 перечислены все символы и их значения. Примеры, приведенные ниже, следует читать в соответствии с таблицей. Специальный смысл любого символа может быть отменен предшествующей ему обратной дробной чертой ''.
с |
Любой специальный символ задает совпадение с таким же символом |
c |
Отменяет специальный смысл символа с |
А |
Соответствует началу строки, когда ^ начинает образец |
$ |
Соответствует концу строки, когда $ заканчивает образец |
. |
Совпадает с любым одиночным символом |
[...] |
Соответствует одному любому символу в ... ; допустимы диапазоны типа a-z |
[^...] |
Соответствует любому одиночному символу, не входящему в ... ; допустимы диапазоны |
r* |
Соответствует нулевому или более числу вхождений r , где r символ, или [...] |
& |
Используется только в правой части s; вставляет фрагмент, совпавший с образом |
(...) |
Помечает регулярное выражение; найденная строка доступна как 1 , и т.д. в левой и правой частях выражения |
Таблица П.1.1: Регулярные выражения редактора
Символу перевода строки не соответствует ни одно регулярное выражение.
Образец | Соответствие |
---|---|
/^$/ |
пустая строка, т.е. только конец строки |
/./ |
непустая, т.е. по крайней мере один символ |
/^/ |
все строки |
/thing/ |
thing где либо в строке |
/^thing/ |
thing в начале строки |
/thing$/ |
thing в конце строки |
/^thing$/ |
строка, состоящая лишь из thing |
/thing.$/ |
thing плюс любой символ в конце строки |
/thing.$/ |
thing. в конце строки |
//thing// |
/thing/ где либо в строке |
/[tT]hing/ |
thing или Thing где либо в строке |
/thing[0-9]/ |
thing , за которой одна цифра |
/thing[^0-9]/ |
thing , за которой не цифра |
/thing[0-9][^0-9]/ |
thing , за которой цифра и не цифра |
/thing1.*thing2/ |
thing1 , затем любая строка, затем thing2 |
/^thing1.*thing2$/ |
thing1 в начале и thing2 в конце |
Регулярные выражения, использующие *
, выбирают самое левое совпадение с образцом до тех пор, пока это возможно. Отметим, что x*
может соответствовать нулю, а xx*
одному или более символу.
Глобальные команды
Глобальные команды g
и v
управляют вызовом одной или большего числа других команд, выполняющих преобразования в множестве строк, выбранных регулярным выражением. Команда g
наиболее часто используется для печати, подстановки или удаления множества строк:
m,ng/re/cmd |
Для всех строк между m и n, которые соответствуют re выполнить cmd |
m,nv/re/cmd |
Для всех строк между m и n, которые не соответствуют re выполнить cmd |
Командам g
и v
могут предшествовать номера строк, ограничивающие диапазон; по умолчанию принимается диапазон 1,$
:
g/.../p |
Печатать все строки, соответствующие регулярному выражению ... |
g/.../d |
Убрать все строки соответствующие ... |
g/.../s//repl/p |
Заменить первое вхождение ... в каждой строке на 'repl ', печатать измененные строки |
g/.../s//repl/gp |
Заменить каждое ... на 'repl ' , печатать измененные строки |
g/.../s/pat/repl/ |
В строках, соответствующих ... , заменить первую 'pat ' на 'repl ' |
g/.../s/pat/repl/p |
В строках, соответствующих ... , заменить первую 'pat ' на 'repl ' и печатать |
g/.../s/pat/repl/gp |
В строках, соответствующих ... , заменить все 'pat ' на 'repl ' и печатать |
v/.../s/pat/repl/gp |
В строках, не соответствующих ... , заменить все 'pat ' на 'repl ' и печатать |
v/^$/p |
Печатать все непустые строки |
g/.../cmd1cmd2cmd3 |
Выполнять составные команды с единственной g , присоединить к каждой cmd кроме последней |
Команды, управляемые командами g
или v
, также могут использовать номера строк, текущая строка настраивается по очереди на каждую выбранную строку:
g/thing/.,.+1р |
Печатать каждую строку с thing и следующую |
g/^.EQ/.1, /^.EN/s/alpha/beta/gp |
Заменять alpha на beta только между .EQ и .EN и печатать измененные строки |
Перемещение и копирование строк
Команда m
перемещает группу смежных строк, а команда t
копирует группу строк:
m,n,md |
Переместить строки m по n за строку d |
m,n,td |
Скопировать строки m по n за строку d |
Если исходные строки не определены, используется текущая строка. Строка назначения d
не может быть в диапазоне m,n-1
. Ниже приведено несколько общих идиом, включающих m
и t
.
m+ |
Поместить текущую строку после следующей (переставить) |
m-2 |
Поместить текущую строку перед предыдущей |
m-- |
То же самое: это то же, что -2 |
m- |
Ничего не делать |
m$ |
Поместить текущую строку в конец (m0 — поместить в начало) |
t. |
Дублировать текущую строку (t$ дублирует в конце) |
-,.t. |
Дублировать предыдущую и текущую строки |
1,$t$ |
Дублировать все множество строк |
g/^/m0 |
Инвертировать порядок строк |
Метки и номера строк
Команда =
печатает номер строки $
(слабое умолчание), .=
печатает номер текущей строки и т.д. Положение текущей строки не изменяется.
Команда kc
метит нужную строку буквой с
; впоследствии на эту строку можно ссылаться с помощью 'c
. Команда k
не меняет положение текущей строки. Метки удобны при перемещении больших фрагментов текста, поскольку они остаются привязанными к строкам, как показано в приведенной ниже последовательности:
/.../ka |
Найти строку ... и пометить буквой a |
/.../kb |
Найти строку ... и пометить буквой b |
'a,'bp |
Печатать целый диапазон, чтобы быть уверенным |
/.../ |
Найти нужную строку |
'а,'bm |
Поместить выбранные строки после нее |
Объединение, расщепление и реорганизация строк
Строки могут быть объединены с помощью команды j
(пробелы не добавляются):
m,nj |
объединяет строки с m по n в одну |
jp |
Объединить текущую строку со следующей и печатать |
-,.jp |
Объединить предыдущую строку с текущей и печатать |
По умолчанию принимается диапазон .,.+1
;
Строки можно расщепить командой подстановки, отделив новую строку:
s/part1part2/part1part2/ |
Расщепить строку на две части |
s/ / /g |
Расщепить по каждому пробелу. Оставить одно слово на строку |
Текущей становится последняя созданная строка.
Чтобы манипулировать не только целыми фрагментами, выбираемыми регулярными выражениями, но и их соответствующими частями, используйте помеченные регулярные выражения: если конструкция (...)
появляется в регулярном выражении, то часть соответствующего ей фрагмента доступна как 1
. Возможно до девяти помеченных выражений, на которые ссылаются с помощью 1
, 2
и т.д.
s/(...)(.*)/21/ |
Поместить 3 первых символа в конец |
/(..*)1/ |
Найти строки, содержащие повторяющиеся смежные цепочки символов |
Команды, работающие с файлами
Командам r
и w
(читать и писать) могут предшествовать номера строк:
nr file |
Читать file ; добавить его после строки n; текущей становится последняя прочитанная строка |
m,nw file |
Писать строки m-n в file ; положение текущей строки не изменяется |
m,nw file |
Добавить строки m-n к file ; положение текущей строки не изменяется |
По умолчанию диапазон для w
и W
(команда W
приведена ниже в табл. П.1.2) — это целый файл. Значение n по умолчанию для r
равно $,
что представляется не очень удачным. Будьте внимательны.
Редактор ed
запоминает первое использованное имя файла из командной строки или из команд r
, w
. Команда f
(файл) печатает или заменяет имя запомненного файла:
f |
Печатать имя запомненного файла |
f file |
Установить запомненное имя на 'file ' |
Команда e
(редактировать) вновь вызывает ed с запомненным или новым файлом:
e |
Начать редактировать запомненный файл |
e file |
Начать редактировать 'file ' |
Команда е
защищена тем же способом, что и q
: если вы не записали измененную версию, первая команда е
выдает сообщение об ошибке; е
вновь инициализирует редактор независимо от внесения изменений. В некоторых системах ed
связан с е
, так что одна и та же команда (е filename
) может использоваться внутри и вне редактора.
Шифрование
Файлы могут быть зашифрованы по записи и дешифрованы при чтении с помощью команды x
; пароль будет запрошен. Шифрование происходит тем же способом, что и в crypt(1)
. В некоторых системах команда x
заменена на X
(прописную букву) во избежание случайностей.
Сводка команд
В табл. П.1.2 перечислены команды редактора, а в табл. П.1.3 допустимые номера строк. Каждой команде предшествует нуль, один или два номера строк, указывающие число используемых строк, если их нет, принимается соглашение по умолчанию. За большинством команд может следовать буква p для вывода последней обработанной строки или 1 для формата списка. Текущей обычно становится последняя обработанная строка; настройка не меняется командами f
, k
, w
, x
, =
, !
.
.а |
Выполнять ввод до тех пор, пока не напечатана строка, содержащая только '. ' |
.,.с |
Заменить строки, новый текст заканчивается так же, как для команды а |
.,.d |
Исключить строки |
е file |
Вновь начать редактировать file . Редактирование начинается даже в том случае, если исправления не записаны |
f file |
Запомнить имя файла как file |
1,$g/re/cmds |
Выполнить cmds для каждой строки, соответствующей регулярному выражению re; отдельные команды в cmds разделены newline (+"перевод строки") |
.i |
Вставить текст перед строкой; он заканчивается так же, как для команды a |
.,.+1j |
.Соединить строки в одну |
.kc |
Пометить строку буквой с |
...l |
Перечислить строки, делая невидимые символы видимыми |
.,.m line |
Переместить строки после строки line |
.,.p |
Печатать строки |
q |
Выйти. Q выходит, даже если исправления не записаны |
$r file |
Читать file |
.,.s/re/new/ |
Заменить new на то, что соответствует re |
.,.t line |
Скопировать строки после line |
.u |
Аннулировать последнюю подстановку в строке (только одну) |
1,$v/re/cmds |
Выполнить команды ed cmds для каждой строки, не соответствующей re |
1,$w file |
Записать строки в файл; W добавляет (строки к файлу) вместо того чтобы записывать (как новый файл) |
X |
Войти в режим шифрования (или ed -х имя_файла) |
$= |
Печатать номер строки |
! cmdline |
Выполнить команду UNIX cmdline |
(.+1) newline |
Печатать строку |
Таблица П.1.2: Сводка команд ed
n | Абсолютный номер строки n, n = 0,1, 2,... |
. |
Текущая строка |
$ |
Последняя строка текста |
/re/ |
Следующая строка, соответствующая re ; после последней $ циклическое движение к первой строке |
?re? |
Предыдущая строка, соответствующая re; после первой циклическое движение к последней $ |
'c |
Строка с меткой с |
N1+/-n |
Строка N1+/-n (аддитивная комбинация) |
N1,N2 |
Строки с N1 по N2 |
N1;N2 |
Команда: сделать строку N1 текущей, затем вычислить N2. N1 и N2 могут быть определены любым из перечисленных выше способов |
Таблица П.1.3: Номера строк в ed
Упражнение
Если вы думаете, что знаете ed
, попробуйте выполнить текст (см. справочное руководство по quiz(6)
).
- Предисловия
- Глава 1 UNIX для начинающих
- Глава 2 Файловая система
- Глава 3 Возможности интерпретатора shell
- Глава 4 Фильтры
- Глава 5 Программирование на языке shell
- Глава 6 Программирование с помощью стандартных функций ввода-вывода
- Глава 7 Системные вызовы в UNIX
- Глава 8 Разработка программ
- Глава 9 Подготовка документации
- Глава 10 Эпилог
- Приложение 1 Краткое описание редактора
- Приложение 2 Справочное руководство по hoc
- Приложение 3 Исходные тексты калькулятора hoc
- Сноски из книги
- Содержание книги
- Популярные страницы
- Приложение 1 Краткое описание редактора
- Приложение 9 Акт выполненных работ (к Договору на оказание информационных услуг)
- Приложение 21 Образец должностной инструкции начальника отдела по работе с сетевыми клиентами
- Приложение 19 Образец должностной инструкции мерчендайзера
- Приложение I Диаграммы взаимовлияния
- Приложение 10. Коды ошибок
- Приложение 1 Оптические процессоры
- Приложение 1 Тестирование ПК при включении
- Приложение 2 Интернет-ресурсы
- Приложение 3 Производители компьютерного оборудования в Интернете
- Приложение 4 Материнская плата, основные термины
- 5.2. Основные приемы работы, элементы текстового редактора