SAVEDIFS=$IFS
IFS=:
HOLD_FILE=hold_file
NAME_MATCH="James Lenod"
INPUT_FILE=names.txt
# создавайте каждый раз новый HOLD_FILE, в случае, когда сценарий
непрерывно выполняется
>$HOLD FILE
while read NAME DEPT ID
do
#выводит на экран всю информацию в holdfile с помощью перенаправления
echo $NAME $DEPT $ID >>$HOLD_FILE
#имеется ли соответствие ???
if [ "$NAME"="$NAME_MATCH" ]; then
# да, тогда удобно завершить работу
echo "all entries up to and including $NAME_MATCH are in $HOLD_FILE"
exit 0
fi
done < $INPUT_FILE
# восстановление IFS
IFS=$SAVEDIFS
Выполним следующий шаг и уточним количество служащих в каждом из отделов. Сохраним прежний формат просмотра, в котором каждому полю присваивается название переменной. Затем для добавления каждого совпадения с помощью оператора case просто применим команду expr. Если обнаруживается неизвестный отдел, его название выводится на экран в виде стандартного потока ошибок; поэтому, если отдел не существует, нет необходимости прерывать выполнение сценария.
$ pg whileread_cond
#!/bin/sh
# whileread_cond
# инициализация переменных ACC_LOOP=0; CUS_LOOP=0; PAY_LOOP=0;
SAVEDIFS=$IFS
IFS=:
while read NAME DEPT ID
do
# счетчик увеличивается на единицу для каждого совпадающего названия отдела.
case $DEPT in
Accounts)
ACC_LOOP=`expr $ACC_LOOP + 1`
ACC="Accounts"
;;
Customer)
CUS_LOOP=`expr SCUS_LOOP + 1`
CUS="Customer"
;;
Payroll)
PAY_LOOP=`expr $PAY_LOOP + 1`
PAY="Pay roll"
;;
*) echo "`basename $0`: Unknown department $DEPT" >&2
;;
esac
done < names.txt
IFS=$SAVEDIFS
echo "there are $ACC_ LOOP employees assigned to $ACC dept"
echo "there are $CUS_LOOP employees assigned to $CUS dept"
echo "there are $PAY_LOOP employees assigned to $PAY dept"
При выполнении сценария получим следующий вывод:
$ whileread_cond
there are 2 employees assigned to Accounts dept
there are 1 employees assigned to Customer dept
there are 2 employees assigned to Payroll dept
18.7.6. Выполнение суммирования
Довольно часто приходится сталкиваться с задачей считывания информации из файла и выполнения суммирования по определенным столбцам, содержащим числа. Предположим, в файле total.txt находятся данные о продажах отделами stat и gift..
$ pg total.txt
STAT | 3444 |
GIFT | 233 |
GIFT | 252 |
GIFT | 932 |
STAT | 212 |
STAT | 923 |
GIFT | 129 |
Задача состоит в подсчете общей суммы всех записей отдела gift. Чтобы сохранить общие значения сумм, применим оператор expr. Как показано в следующем операторе expr, переменным loop и total первоначально вне цикла присваивается значение ноль. Когда сценарий выполняет цикл, значение переменной items добавляется к значению переменной total. В первую итерацию цикла входит только первый пункт, но в дальнейшем к накапливающимся значениям переменной total добавляются значения переменной items.
Следующий оператор expr увеличивает значение счетчика.
LOOP=0
TOTAL=0
while…
TOTAL=`expr $TOTAL + $ITEMS`
ITEMS=`expr $ITEMS + 1`
done
Очень распространенной является такая ошибка: при работе с оператором expr забывают сначала инициализировать переменную.
LOOP=0
TOTAL=0
Если переменная не инициализирована, на экране появится сообщение об ошибочном применении оператора expr. При необходимости можно инициализировать переменную в цикле:
TOTAL=`expr ${TOTAL:=0} + ${ITEMS}`
В вышеприведенном примере переменной total присваивается значение нуль, если эта переменная не имеет значения. Чаще распространен первый вариант инициализации переменных с помощью оператора expr. Не забывайте выводить на экран конечное общее значение, полученное в результате выполнения цикла.
Рассмотрим следующий сценарий.
$ pg total
#!/bin/sh
#общая сумма
#инициализация переменных
LOOP=0
TOTAL=0
COUNT=0
echo "items Dept"
echo " "
while read DEPT ITEMS do
# сохраните результаты подсчета при просмотре общих записей
COUNT=`expr $COUNT + 1`
if [ "$DEPT"="GIFT" ]; then
# сохраните выполнение суммирования TOTAL=`expr $TOTAL + $ITEMS` ITEMS=`expr $ITEMS + 1`
echo -e "$ITEMS\t$DEPT"
fi
#echo $DEPT $ITEMS done < total.txt
echo $TOTAL
echo "There were $COUNT entries altogether in the file"
При выполнении сценария получим:
$ total
Items |
Dept |
234 |
GIFT |
253 |
GIFT |
933 |
GIFT |
130 |
GIFT |
====== |
====== |
1546 |