6.14. Работа со строками

6.14.1. Разбиение строк

Редактор обеспечивает возможность разбиения строки на несколько более коротких строк путем вставки символов новой строки. Например, строка:

	текст xy текст 
может быть разбита на две между символами "x" и "y" следующим образом:
        s/xy/x\
        y/
команда:
        s/xy/x\
        zzz\
        y/
разобьет исходную строку на три, при этом будет добавлена строка "zzz".

6.14.2. Объединение строк (j)

Объединение строк осуществляется с помощью команды "j". Например, если имеются строки:

	текст x 
	y текст
то установив первую строку текущей и задав команду "j", получим:
	текст xy текст 

Можно объединить все строки в одну большую строку и распечатать ее.

6.14.3. Копирование строк (t)

Для копирования строк текста в буфере редактора используется команда "t".

Формат команды:

	[n[, k]]tl<CR>
где n, k - номера начальной и конечной заменяемых строк;
t - имя команды копирования;
l - номер строки, после которой размещаются копируемые строки с номерами от "n" до "k" включительно.

По данной команде строки с номерами от "n" до "k" включительно пересылаются на место после строки с номером "l".

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

Если номер строки не задан, то пересылается текущая строка.

Строки с номерами от "n" до "k" включительно сохраняются на своем прежнем месте.

Команду "t" удобно использовать для создания текстов с повторяющимися данными.

Пример.

        1, 7t15
группу строк с 1-й по 7-ю поместить после 15-й строки.

6.14.4. Перестройка строк

Предположим, что в начале каждой строки файла стоят имена вида:

        Петров П.К.
        Иванов С.Б 
и т.д., требуется переделать текст таким образом, чтобы инициалы стояли перед фамилиями, т.е.
        П.К. Петров
        С.Б. Иванов 

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

Альтернативный метод заключается в том, чтобы отметить элементы строки (в данном случае фамилию и инициалы), а затем переставить эти элементы. Если в левой части команды подстановки "s" какой-либо элемент образца заключен в "\(" и "\)", то он запоминается и может использоваться в правой части команды. В правой части команды обозначение "\1" относится к тому, что соответствало первой паре \(...\), "\2" - второй паре и т.д.

Следующая команда:

	1, $s/^\([^ ]*\) *\(.*\)/\2 \1/
выполняет нужную работу, хотя ее и трудно прочитать. Первая пара \(...\) соответствует фамилии, которая представляет собой любую строку символов вплоть до пробела; в правой части команды на нее выполняется ссылка с помощью "\1". Вторая пара \(...\) обозначает то, что стоит после запятой и любого количества пробелов, а ссылка на нее выполняется с помощью "\2".

6.14.5. Маркеры

Редактор ed позволяет пометить строку некоторым именем, чтобы впоследствии обращаться к ней по этому имени независимо от фактического номера строки. Это удобно при перемещении строк и отслеживании их по мере перемещения. Для маркировки используется команда назначения имени. Если ввести команду "kx", то текущая строка будет отмечена маркером с именем "x". Если перед "k" указывается номер строки, будет отмечена соответствующая строка. (Имя должно представлять собой одну строчную букву латинского алфавита). После этого можно ссылаться на отмеченную строку с помощью адреса "'x".

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

	a 
	   Первая строка вводимого текста
	   Вторая строка
	   Третья строка
	   Последняя строка
	   .
	   -3
	   ka
	   2
	   kb
	   $
	   'a, 'bm
в результате будет получена следующая последовательность строк:
   Третья строка
   Последняя строка
   Первая строка вводимого текста
   Вторая строка 

6.14.6. Адресация строк в редакторе

6.14.6.1. Адресная арифметика

Рассмотрим использование указателей строк вида ".", "$", "/.../" и "?...?" в сочетании с действиями "+" и "-". Так, команда:

	$-1
выдает предпоследнюю строку текущего файла.

Команда:

	$-5, $p 
распечатывает последние шесть строк. Если в файле нет шести строк, будет выдано сообщение об ошибке ("?").

Команда:

	.-3, .+3p 
распечатывает 7 строк, из них три строки до и три строки после текущей строки. Знак "+" может быть опущен. Знак "-" сам по себе представляет собой команду для возврата на одну строку в файле.

Команда:

	---
вызывает возврат на три строки, как и команда "-3".

Команда:

	-, .s/bad/good/
вызывает замену "bad" на "good" в текущей и пред- шествующей ей строках.

Знаки "+" и "-" могут использоваться при поиске с помощью "/.../", "?...?" и с "$". По команде:

	/текст/--
разыскивается строка, содержащая "текст", после чего текущей строкой становится строка вторая перед найденной строкой.

6.14.6.2. Номера строк и указатель текущей строки

Разрешается определять диапазон "n,m" (от строки с номером "n" до строки с номером "m"), где "n" - номер начальной строки, а "m" - номер конечной строки. Весь файл целиком с первой до последней строки задается диапазоном "1, $". Так, команда:

	1, $p 
вызывает выдачу всех строк файла.

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

Пример.

Команда:

	5p 
устанавливает указатель текущей записи на пятую строку.

В любой момент времени можно определить, каков текущий номер строки. Это делается с помощью команды ".=".

Использование этой команды полезно после внесения многочисленных изменений в файл.

Можно указать несколько строк, задав диапазон "от, до". Указатель текущей строки "." можно использовать на месте начальной или конечной строки диапазона. Так, команда:

	., $p 
печатает все строки от текущей до конца файла.

6.14.6.3. Изменение указателя текущей строки

При использовании команд поиска просмотр всегда начинается с текущей строки и продолжается в прямом или обратном направлении до тех пор, пока не будет обнаружена строка с искомым текстом. Например, если буфер содержит строки:

        .
        АБ
        .
        .
        БВ
        .
и, если текущая строка - первая, то команда:
	/А/, /Б/p 
не распечатает строки, расположенные в промежутке от строки "АБ" до строки "БВ", так как при использовании запятой в качестве разделителя указателей строк, номер текущей строки не изменяется после обработки каждого адреса, каждый поиск начинается от текущей строки. В результате будет распечатана одна строка "АБ".

При указании диапазона адресов вместо запятой используется точка с запятой. Символ ";" вызывает установку в то место, которое определяется при вычислении номеров строк. Фактически редактор "перемещает" указатель текущей строки. Команда:

	/А/; /Б/p 
распечатывает строки в диапазоне от "АБ" до "БВ", т.к. после нахождения строки с "А" эта строка становится текущей и поиск "Б" начинается после этой строки.

6.14.6.4. Прерывание работы редактора

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

Более определенно прерывается команда печати. Положение указателя текущей строки не изменяется до тех пор, пока печать не завершится. Таким образом, если запущена команда печати и она не напечатала нужную строку, при нажатии клавиши прерывания текущей строкой останется та строка, которая была в момент запуска команды "p".

6.14.7. Глобальные команды

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

Глобальная команда в строке должна быть первой, затем идет образец и команды редактора. Допускается написание нескольких команд редактора, но в этом случае каждая команда должна располагаться на отдельной строке, и каждая строка, за исключением последней, должна заканчиваться символом "\".

6.14.7.1. Команда g

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

Общий вид командной строки (строк) с использованием команды "g" следующий:

	g/образец/ команда или перечень команд<CR>
Примеры.
	g/abdc/p 
печать всех строк буфера, содержащих последовательность "abdc";
	g/abcd/s//efjc/gp 
замена и печать всех строк буфера, в которых найдена последовательность "abcd";
	1, $s/abcd/efjc/gp 
замена во всех строках последовательности "abcd" на "efjc" и печать последней заменяемой строки;
	g/xxx/.-1s/abc/def/\
	.+2s/ghi/jkl/\
	.-2, .p 
замена в строках до и после каждой строки, содержащей "xxx", и печать всех трех строк.

6.14.7.2. Команда v

Команда "v" аналогична команде "g" за исключением того, что она работает с теми строками, которые не содержат заданный образец.

Общий вид командной строки (строк) при использовании команды "v":

	v/образец/ команда или перечень команд<CR>
Пример.
	v/xxx/s/aaa/bbb/
заменить во всех строках файла последовательность "aaa" на "bbb" кроме строк, в которых имеется последовательность "xxx".

Назад | Содержание | Вперед