Литмир - Электронная Библиотека
Содержание  
A
A

sed 3q

Хотя

3q
не является законной командой
ed
, для
sed
она имеет смысл: копировать строки и завершить выполнение после третьей.

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

sed
пропустить через команду
ind
, но поскольку редактор
sed
допускает несколько команд, можно сделать это путем одного обращения к
sed
(хотя и несколько необычного):

sed 'S/^/→/

3q'

Обратите внимание, где находятся кавычки и символ перевода строки: команды должны быть на отдельных строках, но редактор игнорирует пробелы и символы табуляции в начале строки.

Представляется естественным с помощью рассмотренных выше приемов составить программу

head
, которая будет печатать несколько строк из каждого своего файла-аргумента. Но
sed 3q
(или
10q
) настолько просто задать, что в этом никогда не возникало потребности. Однако мы ввели команду
ind
, так как соответствующая последовательность для
sed
длиннее. (В процессе работы над книгой мы заменили существовавшую программу на языке Си в 30 строк на одну строку команды
ind
версии 2, приведенной выше.) Четкого критерия в отношении того, когда имеет смысл создавать отдельную программу из сложной командной строки, нет, поэтому мы предлагаем вам свое решение: поместите программу в свой каталог
/bin
и посмотрите, будете ли вы ее действительно применять.

Можно помещать команды редактора

sed
в файл и выполнять их, получая оттуда с помощью обращения:

$ sed -f командный_файл

Вы можете обращаться к строкам, используя не только их номера. Так, команда

$ sed '/шаблон/q'

выдает из входного потока все строки до первой включительно, которые соответствуют шаблону, а команда

$ sed '/шаблон/d'

удаляет каждую строку, содержащую шаблон; удаление происходит до автоматического вывода строк, поэтому удаленные строки не учитываются.

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

-n
; в этом случае в выходном потоке появятся только строки, задаваемые явной командой вывода p. Например,

$ sed -n '/шаблон/p'

эквивалентен команде

grep
. Условие сопоставления можно инвертировать, если завершить его символом
!
, поэтому

$ sed -n '/шаблон/!p'

эквивалентно команде

grep -v
. (Так же, как
sed '/шаблон/d'
.)

Для чего нужны две команды

sed
и
grep
? В конце концов,
grep
— всего лишь частный случай команды
sed
. Это в какой-то степени объясняется историческими причинами: команда
grep
появилась намного раньше, чем команда
sed
. Но она не только уцелела, но и активно применялась. В силу специфики назначения обеих команд
grep
значительно проще использовать, чем команду
sed
, так как ее использование в типичных ситуациях настолько лаконично, насколько возможно (к тому же у нее есть возможности, отсутствующие у команды
sed
; см., например, описание флага
-b
). Но все-таки программы могут "умирать". Когда-то была программа с именем
gres
, выполняющая простую подстановку, но она исчезла почти мгновенно, когда появилась команда
sed
.

Используя запись, такую же, как в редакторе

ed
, можно вставлять символы перевода строк с помощью команды
sed
:

$ sed '/$/\

> /'

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

$ sed 's/[→][→]*/\

>/g'

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

'[→]'
задает пробел или символ табуляции,
'[→]*'
задает нуль или более таких символов, а весь шаблон — один или более пробелов и/или символов табуляции.)

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

$ sed -n '20,30p'      
Печать только строк с 20-й по 30-ю

$ sed '1,10d'          
Удаление строк с 1-й до 10-й (=tail +11)

$ sed '1,/^$/cd'       
Удаление всех строк до первой пустой включительно

$ sed -n '/^$/,/^end/p'
Печать всех групп строк, начиная от пустой строки до

строки, начинающейся с end

$ sed '$d'             
Удаление последней строки

Строки нумеруются с начала входного потока; обнуление не происходит с началом нового файла.

У команды

sed
есть существенное ограничение, которое, однако, отсутствует в редакторе
ed
: в ней поддерживается относительная нумерация строк. В частности, операции
+
и
-
не действуют в выражениях, задающих номера строк, поэтому невозможно двигаться назад во входном потоке:

$ sed '$-1d'
Недопустима обратная адресация

Unrecognized command: $-1d

$

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

sed
, но он слишком изощренный. (См. команду
hold
в справочном руководстве по UNIX.) Невозможна и относительная прямая адресация:

$ sed '/что-то/+1d'
Недопустима прямая адресация

Редактор

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

$ sed -n '/шабл/w файл1

> /шабл/!w файл2' имена_файлов...

48
{"b":"248117","o":1}