sed
, но он слишком изощренный. (См. команду hold
в справочном руководстве по UNIX.) Невозможна и относительная прямая адресация:$ sed '/что-то/+1d'
Недопустима прямая адресацияРедактор
sed
имеет возможность записывать в несколько выходных файлов. Например, команда$ sed -n '/шабл/w файл1
> /шабл/!w файл2' имена_файлов...
$
записывает строки, соответствующие
"шабл"
, в файл1
, а не соответствующие — в файл2
, или, если вернуться к нашему первому примеру:$ sed 's/\UNIX(TM)/gw u.out' имена_файлов...> выход
то здесь, как и ранее, весь выходной поток записывается в файл
"выход"
, но к тому же измененные строки записываются в файл u.out
.Иногда нужна помощь со стороны интерпретатора, чтобы в команду редактора включить аргументы командного файла. Одним из примеров служит программа
newer
, которая выдает все более новые, чем заданный, файлы каталога:$ cat newer
# newer f: список файлов, созданных после f
ls -t | sed '/'$1'$/q'
$
Кавычки защищают различные специальные символы, предназначенные для редактора, оставляя
$1
открытым для интерпретатора, чтобы он заменил его на имя файла. Существует альтернативный способ записи аргумента:"/^$1\$/q"
так как
$1
заменяется на аргумент, тогда как \$
становится просто $
.Аналогично можно составить программу
older
, которая выдает в качестве параметра все файлы, более старые, чем заданный:$ cat older
# older f: список файлов, созданных ранее f
ls -tr | sed '/'$1'$/q'
$
Единственное различие состоит в применении флага
-r
в команде ls
для изменения порядка выдачи файлов.Хотя редактор
sed
способен на гораздо большее, чем мы вам продемонстрировали, включая проверку условий, циклы и ветвления, запоминание предыдущих строк, и, конечно, в нем допустимы многие команды редактора ed
, описанные в приложении 1. Тем не менее в основном sed используется так, как было показано; одна или две простые команды редактирования, а не длинные и сложные последовательности. В табл. 4.2 собраны некоторые команды sed
, хотя и не приведены операции над несколькими строками.a\
Добавлять строки к выходному потоку, пока одна из них не закончится на \
b label
Перейти на команду: label
c\
Заменить строки на последующий текст, как в команде a
d
Удалить строку; прочесть следующую входную строку i\
Вставить последующий текст перед следующим выходным потоком l
Выдать строку, напечатав все невидимые символы p
Выдать строку q
Выйти r file
Читать file
, содержимое его переслать в выходной поток s/old/new/f
Заменить old
на new
. Если f
=g
, заменить все вхождения; f
=p
, вывод; f
=w
файл, запись в файл t label
Проверка: переход на метку, если была замена в текущей строке w file
Записать строку в файл y/str1/str2/
Заменить каждый символ строки str1
на соответствующий символ строки str2
(диапазоны недопустимы) =
Выдать текущую нумерацию входной строки !cmd
Выполнить команду sed cmd
, только если строка не выбрана : label
Установить метку для команд b
и t
{
Команды до соответствующей скобки }
рассматривать как группу
Таблица 4.2: Сводка команд sed
Редактор
sed
удобен потому, что позволяет работать с произвольно длинными входными строками. Это "быстрый" редактор, который сходен с редактором ed
в интерпретации регулярных выражений и в обработке отдельных строк. Однако, с другой стороны, его возможности запоминания ограничены (трудно запомнить текст от одной строки до другой) — делается только один проход по данным, нельзя двигаться назад, нет способов прямой адресации типа /.../+1:
и нет средств для работы с числами, т.е. он является чисто текстовым редактором.Упражнение 4.5Измените команды
older
и newer
так, чтобы они не включали файл-аргумент в свой выходной поток. Измените их так, чтобы файлы выдавались в обратном порядке.Упражнение 4.6С помощью редактора
sed
сделайте программу bundle
совершенно надежной. Подсказка: в конструкции "документ здесь" слово, отмечающее конец данных, распознается только в том случае, когда оно совпадает со строкой полностью.4.4 Язык awk
поиска и обработки шаблонов
Некоторые ограничения
sed
преодолены в программе awk
. Принцип работы этой программы сходен с принципом работы программы sed
, но синтаксически она ближе к языку программирования Си, чем к текстовому редактору. Способ задания команды такой же, как и для sed
:$ awk 'программа' имена_файлов...
но программа другая:
шаблон {действие}
шаблон {действие}
...
Программа
awk
читает входной поток по одной строке из указанных файлов. Строки сопоставляются с шаблонами по порядку; для каждого шаблона, соответствующего строке, выполняется необходимое действие. Как и в редакторе sed
, входные файлы здесь не изменяются.Шаблоны могут быть регулярными выражениями в
sed
или более сложными условиями, напоминающими язык Си. Приведем простой пример (такого же результата можно добиться с помощью команды egrep
):$ awk '/регулярное_выражение/ {print}' имена_файлов...
Печатается каждая строка, соответствующая регулярному выражению.
Шаблоны или действия могут отсутствовать. Если отсутствует действие, то по умолчанию печатаются строки, соответствующие шаблону, поэтому команда
$ awk '/регулярное_выражение/' имена_файлов...
эквивалентна предыдущей. Наоборот, если отсутствует шаблон, то действие выполняется для каждой входной строки. Следовательно, команда
$ awk '{print}' имена_файлов...
дает те же результаты, что и команда
cat
, хотя действует медленнее.Теперь перейдем к более интересным примерам, но прежде сделаем одно замечание. Как и в случае
sed
, программу команды awk
можно получать из файла:$ awk -f кмд файл имена_файлов...
Поля. В программе
awk
каждая входная строка автоматически разбивается на поля, т.е. последовательности символов без пробелов, разделенные пробелами и символами табуляции. По этому определению выходной поток команды who
имеет пять полей:$ who
you tty2 sep 29 11:53