······sed −n — f $sedscript $1 | uniq | more
····fi
··}
··trap "$(which rm) −f $tempout $sedscript" EXIT
··if [-z "$1"]; then
····echo "Usage: $0 [-c X] pattern {filename}" >&2
····exit 0
··fi
··if ["$1" = "-c"]; then
····context="$2"
····shift; shift
··elif ["$(echo $1|cut −c1-2)" = "-c"]; then
····context="$(echo $1 | cut −c3-)"
····shift
··fi
··pattern="$1"; shift
··if [$# −gt 0]; then
····for filename; do
······echo "- $filename —"
······showMatches $filename
····done
··else
····cat — > $tempout # Записать поток во временный файл.
····showMatches $tempout
··fi
··exit 0
Этот сценарий задействует команду grep −n, чтобы получить номера всех совпавших строк в файле
, и затем, используя заданное число строк контекста, определяет номера начальной
и конечной
строк для включения в контекст. Эти номера выводятся во временный сценарий для sed, объявленный в
, который выполняет команду поиска с заменой, чтобы добавить к найденному совпадению ANSI-последовательности включения и выключения вывода жирным шрифтом. Перечисленные операции составляют почти 90 % сценария.
Также следует отметить использование команды trap
, которая позволяет включать обработку событий в цикл выполнения сценария командной оболочкой. В первом аргументе ей передается последовательность команд, которую следует выполнить, а в остальных — имена сигналов (событий). В данном случае мы сообщаем оболочке, что в момент выхода из сценария она должна вызвать команду rm, чтобы удалить два временных файла.
Самое примечательное в команде trap — она сработает в любом случае, независимо от того, в какой точке сценария произойдет выход. В последующих сценариях вы увидите, что с помощью trap можно обработать самые разные сигналы, а не только SIGEXIT (или EXIT, или числовой эквивалент сигнала SIGEXIT, который равен 0). Фактически несколькими вызовами команды trap можно определить последовательности команд для обработки нескольких разных сигналов, то есть реализовать вывод сообщения «временные файлы стерты», если кто-то пошлет сценарию сигнал SIGQUIT ( ctrl-C), которое не будет выводиться в случае обычного события выхода (SIGEXIT).
Сценарий может работать со стандартным вводом, сохраняя входные данные во временный файл и затем обрабатывая его, как если бы имя этого файла было получено из аргумента командной строки, или со списком файлов, указанных в командной строке. В листинге 4.14 показан пример передачи единственного файла через аргумент командной строки.
Листинг 4.14.Тестирование сценария cgrep
$ cgrep −c 1 teacup ragged.txt
- ragged.txt —
in the wind, and the pool rippling to the waving of the reeds-the
rattling teacupswould change to tinkling sheep-bells, and the
Queen’s shrill cries to the voice of the shepherd boy-and the
Усовершенствование сценария
После некоторого усовершенствования этот сценарий мог бы добавлять номера к выводимым строкам с совпадениями.
№ 33. Работа со сжатыми файлами
За годы разработки Unix немногие программы пересматривались и переделывались чаще, чем compress. В большинстве систем Linux доступны три основные программы сжатия: compress, gzip и bzip2. Каждая создает файлы со своим расширением ( .z, gz и .bz2 , соответственно), и степень сжатия может отличаться, в зависимости от формы данных в файлах.
Независимо от степени сжатия и от используемых для него программ, работа со сжатыми файлами во многих системах Unix требует распаковать их вручную, выполнить желаемые операции с данными и повторно упаковать их по завершении. Это довольно утомительное занятие, которое точно стоит автоматизировать! Сценарий, представленный в листинге 4.15, действует как удобная обертка для выполнения трех распространенных операций со сжатыми файлами: cat, more и grep.
Листинг 4.15:Сценарий zcat/zmore/zgrep
#!/bin/bash
# zcat, zmore и zgrep — сценарию следует присвоить три имени
#·· с помощью символических или жестких ссылок. Это позволит прозрачно
#·· работать со сжатыми файлами.
Читать дальше