Linux и UNIX: программирование в shell. Руководство разработчика
Шрифт:
$ total
Items
Dept
234
GIFT
253
GIFT
933
GIFT
130
GIFT
======
======
1546
There were 7 entries altogether in the file
18.7.7. Одновременный просмотр двух записей
В некоторых случаях возникает необходимость в одновременной обработке двух записей, например, если нужно сравнить различные поля двух записей. Чтобы просматривать одновременно по две записи, достаточно после первой конструкции "while read" поместить оператор "do" с другим оператором "read". Применяя эту методику, следует помнить, что количество записей для просмотра составляет четное число. Не забывайте проверять число просматриваемых записей!
Ниже приводится файл, содержащий шесть записей: record1, record2 и т. д.
$ pg record.txt
record 1
record 2
record 3
record 4
record 5
record 6
В этом примере одновременно просматривается по две записи. Никакой проверки записей в примере не производится.
Ниже приводится соответствующий сценарий.
$ pg readpair
#!/bin/sh
#readpair
#первая запись
while read rec1 do
#вторая запись
read rec2
#выполняется дальнейшая обработка/тестирование для тестирования или
#сравнения обеих записей
echo "This ls record one of a pair :$rec1"
echo "This ls record two of a pair :$rec2"
done < record.txt
С помощью команды wc сначала проверим, что было выполнено четное число записей.
$ cat record.txt | wc -l
б
Имеется шесть записей, поэтому приступим к их обработке.
$ readpair
This ls record one of a pair :record 1
This ls record two of a pair :record 2
This ls record one of a pair :record 3
This ls record two of a pair :record 4
This ls record one of a pair :record 5
This ls record two of a pair :record 6
18.7.8. Игнорирование символа #
При просмотре текстовых файлов возникает необходимость игнорировать или пропускать строки комментария. Ниже приводится типичный пример.
Предположим, что с помощью обычного цикла while просматривается файл конфигурации. Обычно выполняется построчный просмотр.
Однако с помощью оператора case можно игнорировать некоторые строки, начинающиеся с определенных символов. Поскольку символ # является специальным, для его отключения используется символ "\"; затем после символа хэша указывается звездочка, что позволит после хэша размещать любые символы.
Ниже приводится типичный файл конфигурации.
$ pg config
#ЭТО КОНФИГУРАЦИОННЫЙ ФАЙЛ ПОДСИСТЕМЫ АУДИТА
#НЕ РЕДАКТИРУЙТЕ ЕГО! ОН РАБОТАЕТ
#
# задание административного доступа
AUDITSCM=full
#местонахождение подсистем
AUDITSUB=/usr/opt/audit/sub
#серийный номер хэша для продукта
HASHSER=12S90AB3
#КОНЕЦ ФАЙЛА КОНФИГУРАЦИИ!!!
#
Ниже приводится сценарий, где игнорируются символы хэша:
$ pg ignore_hash
#!/bin/sh
# игнорируйте_хэш
INPUT_FILE=config
if [ -s $INPUT_FILE ]; then
while read LINE
do
case $LINE in
\#*) ;; # игнорировать все символы хэша
*) echo $LINE
;;
esac
done < $INPUT_FILE
else
echo "`basename $0` : Sorry $INPUT_FILE does not exist or ls empty"
exit 1
fi
При выполнении получим:
$ ignore_hash
AUDITSCM=full
AUDITSUB=/usr/opt/audit/sub
HASHSER=12890AB3
18.7.9. Работа с форматированными отчетами
Обычно удаление нежелательных строк целесообразно при просмотре файла отчета. Ниже приводится часть отчета, перечисляющая заказ на канцелярские товары. В данном случае представляют интерес столбцы, содержащие уровень переупорядочения пункта и текущий уровень. Ниже приводится сам отчет.
$ pg order
RE-ORDER REPORT
ITEM
ORDERLEVEL
LEVEL
Pens
14
12
Pencils
15
15
Pads
7
3
Disks
3
2
Sharpeners
5
1
Наша задача заключается в просмотре значения и уточнении, какие пункты следует заказать повторно. Если требуется повторный заказ, нужно дважды его выполнить для данного пункта. Выводной поток данных также должен сообщить, какое количество пунктов нужно заказать повторно, и, кроме того, уточнить общее количество повторных заказов.
Ранее уже рассматривалось, каким образом можно игнорировать строки, начинающиеся определенными символами. Сначала производится чтение из файла. При этом игнорируются все строки, которые начинаются символами # и строками вида "ITEM". После прочтения осуществляется перенаправление данных во временный файл. Затем команда sed применяется для удаления пустых строк. На самом деле все, что делается в этом случае, напоминает фильтрацию текстового файла. Описанные действия реализованы с помощью следующего кода.
$ pg whileorder
#!/bin/sh
# whileorder
INPUT_FILE=order
HOLD=order.tmp
if [ -s $INPUT_FILE ]; then
# пустой файл вывода, добавление не производится!
>$HOLD
while read LINE
do
case $LINE in
\#*|ITEM*) ;; # игнорирование строк, содержащих символы # или ITEM
*)
# перенаправление вывода во временный файл
echo $LINE >$HOLD
;;
esac
done <$INPUT_FILE
# применение команды sed для удаления пустых строк
sed -e '/^$/d' order.tmp > order.$$
mv order.$$ order.tmp
else
echo "`basename $0` : Sorry $INPUT_FILE does not exist or ls empty"
fi
В результате выполнения сценария получаем следующее:
$ pg order.tmp
Pens 14 12
Pencils 15 15
Pads 7 3
Disks 3 2
Sharpeners 5 1
Теперь остается только выполнить считывание временного файла в другом цикле while, а затем реализовать некоторые сравнения с помощью команды expr. Вот соответствующий сценарий: