Linux и UNIX: программирование в shell. Руководство разработчика - Страница 85
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 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