Linux и UNIX: программирование в shell. Руководство разработчика
Linux и UNIX: программирование в shell. Руководство разработчика читать книгу онлайн
Данная книга является практическим руководством по программированию интерпретатора Bourne shell -cтандартного командного интерпретатора в UNIX, полностью совместимого с интерпретатором BASH shell в Linux. Книга предназначена для начинающих и опытных программистов и содержит множество полезных примеров, советов и подсказок. С ее помощью читатель сможет быстро научиться создавать shell–сценарии для реальных задач и ситуаций, возникающих в большинстве систем UNIX и Linux.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
mv $HOLD1 $DBFILE if [ $? -ne 0 ]; then
echo "problems moving the temp sort file..check it out"
exit 1 fi
else
echo " record not saved"
sleep 1 fi
22.2. Удаление записей
Прежде чем удалить запись из файла, ее нужно сначала отобразить для пользователя, чтобы он мог убедиться, что именно эта запись подлежит удалению. После получения подтверждения можно приступать к удалению записи.
При удалении записи выполняются следующие операции:
1. Поиск записи.
2. Отображение записи.
3. Подтверждение процедуры удаления.
4. Обновление файла.
Чтобы найти запись, воспользуемся полем, где содержатся фамилии. После того как пользователь введет фамилию, по которой ведется поиск, можно приступать к
обработке. Можно применить команду grep или утилиту awk. Но поскольку данный файл, скорее всего, содержит не более 100 записей, просмотрим его и определим наличие совпадений.
Если же файл содержит более двух сотен записей, желательно воспользоваться утилитой awk. Это значительно быстрее, чем просмотр файла; к тому же утилита awk более удобна при разделении полей, принадлежащих переменным.
Чтобы применить команду grep или утилиту awk, можно выполнить поиск в файле DBFILE:
echo "enter the surname to search "
read STR
#при работе с awk используйте команду
awk -F: '/$STR/' DBFILE
#при работе с grep используйте команду
grep "$STR" DBFILE
#либо команду
grep "$STR >" DBFILE
Обратите внимание, что при использовании утилиты awk переменную заключают в одинарные кавычки. Если не придерживаться этого условия, не выполняется возврат данных.
Чтобы разделить поля, можно каждому полю назначить переменные (не забывайте, что разделителем полей служит двоеточие). Переменной Ifs нужно присвоить значение двоеточия. Если не сделать этого, запись нельзя будет просматривать. При изменении значения переменной ifs желательно сначала сохранить установки. Благодаря этому их можно будет восстановить по завершении работы сценария.
Чтобы сохранить значения переменной ifs, примените следующую команду:
SAVEDIFS=$IFS
Заменить значение переменной ifs двоеточием можно, выполнив команду
IFS=:
По завершении работы с переменной IFS вы можете легко восстановить ее значение:
IFS=$SAVEDIFS
С помощью функции getrec можно выполнить полномасштабный поиск; этой функции не передаются параметры.
get_rec () {
# get_rec
clear
echo -n "Enter the employee surname :"
read STR
if [ "$STR"="q" ]; then
return 1 fi
REC=0
MATCH=no
if [ "$STR" != "" ]; then
while read CODE F_NAME S_NAME DEPART
do
REC=`expr $REC + 1` tput cup 3 4
echo -n " searching record.. $REC"
if [ "$S_NAME"="$STR" ]; then
MATCH=yes
display_rec
break
else
continue
fi
done <DBFILE
else
echo "Enter a surname to search for or q to quit"
fi
if [ "$MATCH"="no" ]; then
no_recs
fi
}
Пользователь может ввести фамилию или же указать q для завершения выполнения задания. Если указывается фамилия, производится проверка для того, чтобы удостовериться, что фамилия представляет собой вводные данные. Имейте в виду, что удобнее воспользоваться следующей проверкой:
if [ "$STR"! = "" ]; then
Но не такой:
[ -z $STR ]
При выборе первой проверки пользователю достаточно нажать на клавишу [Return], чтобы выполнить команду trap. Во втором случае устанавливается лишь наличие строки нулевой длины.
При считывании значения каждого поля файла используются значащие наименования переменных. Затем при считывании записей применяется счетчик. Действительно, такой прием отражается только на внешней форме сценария и позволяет контролировать процесс поиска записей. Если совпадение найдено, вызывается другая процедура, которая приводит к отображению значений полей. Команда break позволяет прекратить выполнение цикла. Если совпадение не обнаружено, сценарий продолжает выполняться до следующей итерации цикла.
Когда устанавливается соответствие, пользователь получает запрос, действительно ли нужно удалить запись. По умолчанию ответ будет по.
if continue_promptYN "Do You Wish To DELETE This Record" "N"; then
echo "DEL"
grep -v $STR DBFILE >$HOLD1 2> /dev/null
if [ $? -ne 0 }; then
echo "Problems creating temp file $HOLD1.. check it out"
exit 1 fi
Удаление записи выполняется выполнением команды grep с опцией -v. В этом случае с помощью строки STR отображаются все несовпадающие поля. (Эта строка содержит фамилию, которая запрашивается пользователем при удалении записи.)
Поток данных вывода для команды grep перенаправляется во временный файл, где выполняется сортировка. Затем временный файл заменяет исходный файл DBFILE.
При реализации всех перемещений данных выполняется проверка с помощью кода завершения последней команды. Ниже показан поток вывода при удалении записи:
Enter the employee surname :Wilson
searching record,. 6
EMPLOYEE NO: 69232 FIRST NAME : Louise SURNAME : Wilson DEPARTMENT : Accounts
Do You Wish To DELETE This Record [Y..N] [N] :
А теперь приведем полный сценарий, выполняющий удаление записи:
$ pg dbase_del
#!/bin/sh
#dbase_del
#удаление записи
#перехват сигналов
trap "" 2 3 15
#Файл данных
DBFILE=DBFILE
#временные файлы
HOLD1=HOLD1.$$
HOLD2=HOLD2.$$
continue_promptYN(} {
#continue_prompt
_STR=$1
_DEFAULT=$2
#проверим наличие правильных параметров
if [ $# -lt 1 ]; then
echo "continue_prompt: I need a string to "display"
return 1
fi
while : do
echo -n "$_STR [Y..N] [$_DEFAULT]:"
read _ANS
: ${_ANS:=$_DEFAULT}
if [ "$_ANS"="" ]; then
case $_ANS "in
Y) return 0 ;;
N) return 1 ;;
esac
fi
case $_ANS in
у|Y|Yes|YES)
return 0;;
n|N|No|NO)
return 1;;
*) echo "Answer either Y or N, default is $_DEFAULT"
esac
done
}
display_rec()
{
#display_rec
#можно воспользоваться командой cat << документ
tput cup 5 3
echo "EMPLOYEE NO: $CODE" echo "FIRST NAME : $F_NAME" echo "SURNAME :$S_NAME"
echo "DEPARTMENT : $DEPART"
echo -e "nn"
}
no_recs () {
# no_recs
echo -e "nnSorry could not find a record with the name $STR"
}
get_rec () {
# get_rec
clear
echo -n "Enter the employee surname :"
read STR
if [ "$STR"="q" ]; then
return 1
fi
REC=0
MATCH=no
if [ "$STR" != "" ]; then
while read CODE F_NAME S_NAME DEPART
do
REC=`expr $REC + 1`
echo -n " searching record.. $REC"
if [ "$S_NAME" = "$STR" ]; then
MATCH=yes
display_rec
break
else
continue
fi
done << $DBFILE
else
echo "Enter a surname to search for or q to quit"
fi
if [ "$MATCH"="no" ]; then
no_recs
fi
}
SAVEDIFS=$IFS
IFS=:
get_rec
if [ "$MATCH"="yes" ]; then
if continue_promptYN "Do You Wish To DELETE This Record" "N"; then echo "DEL"
grep -v $STR DBFILE >$HOLD1 2> /dev/null if [ $? -ne 0 ]; then