20.1.3. Преобразования файла с помощью команды shift
20.1.3. Преобразования файла с помощью команды shift
Использование возможностей команды shift значительно облегчает работу с опциями командной строки. Рассмотрим сценарий, выполняющий преобразование регистра символов. При этом будет применяться команда tr.
При выполнении сценария используются две опции:
-l для нижнего регистра -u для верхнего регистра
С помощью команды shift можно запустить на выполнение сценарий, работающий с опциями -l и -u. Ниже приводится первый вариант этого сценария.
$ pg tr_case
#!/bin/sh
#tr_case
#преобразование регистра usage ()
{
# сообщение usage
echo "usage:`basename $0` -[l|u] file [files]" >&2
exit 1
}
if [ $# -eq 0 ]; then
# параметры не переданы!
usage
fi
while [ $# -gt 0 ]
do
case $1 in
-u|-U) echo " -uoption specified"
# здесь укажите все установки переменных для нижнего регистра, затем
# примените команду shift shift
;;
-l|-L) echo " -l option specified"
# здесь укажите все установки переменных для верхнего регистра, затем
# примените команду shift shift
;;
*) usage
;;
esac
done
Вначале выполняется проверка, имеются ли аргументы в сценарии. Если они отсутствуют, выводится сообщение usage. При обработке аргументов с помощью конструкции case отображается значение каждой передаваемой опции. После этого применяется команда shift, выполняющая вывод в командной строке очередной опции. Если все опции обработаны, отображается сообщение usage.
А теперь посмотрим, как выглядят выводимые результаты при передаче сценарию двух некорректных аргументов.
$ tr_case -u -l -к
— и option specified
-l option specified
usage: tr_case —[l|u] file [files]
На следующем этапе обрабатываются файлы, передающиеся после обработки опций с помощью конструкции case. Для реализации этой задачи достаточно выполнить небольшие изменения. В конструкции case шаблон * заменяется шаблоном -*, что позволяет передавать некорректные опции, например -p или -q.
Чтобы с помощью цикла for обрабатывать каждый файл, следует для всех передаваемых имен файлов указывать шаблон *. Кроме того, с помощью опции -f проверяется наличие всех требуемых имен файлов.
Итак, улучшенный вариант конструкции case имеет следующий вид:
case
...
-*) usage
*) if [ -f $1 ]; then
FILES=$FILES" "$1 # присвоить переменной имена файлов
else
echo "`basename $0` cannot find the file $1"
fi
shift # получите следующий параметр !
esac
Следует также задать значения некоторых переменных в зависимости от указанной опции (-1, — u). При этом используются следующие переменные:
TRCASE Указывает тип преобразования регистра (верхний или нижний регистр) ЕХТ Все преобразованные файлы имеют либо расширение .UC (для верхнего регистра), либо расширение .LC (для нижнего регистра). В исходный файл изменения не вносятся OPT При передаче опций принимает значение yes, в противном случае — no. Только тогда, когда опции не передаются, можно перехватить их значение и вывести на экран сообщение
Для выполнения реального преобразования достаточно добавить еще один фрагмент кода, включающий команду tr. Этот фрагмент кода добавляется в конец сценария. При этом для считывания имен файлов используется цикл for и конструкция case. Ниже приводится код созданного сценария:
$ pg tr_case
#!/bin/sh
#tr_case
#преобразование символов файлов либо в верхний, либо в нижний регистр
FILES=""
TRCASE=""
EXT=""
OPT=no
# вызывается при неудачном преобразовании
error_msg ()
{
_FILENAME=$1
echo "`basename $0`: Error the conversion failed on $_FILENAME"
}
if [ $# -eq 0 ] then
echo "For more info try `basename $0` —help"
exit 1
fi
while [ $# -gt 0 ]
do
case $1 in
# установите переменные на базе применяемой опции
-u)
TRCASE=upper
ЕХТ=".UС"
OPT=yes
shift
;;
-l)
TRCASE=lower
EXT=".LC"
OPT=yes
shift
;;
-help) echo "convert a file(s) to uppercase from lowercase" echo "convert a file(s) from lowercase to uppercase" echo "will convert all characters according to the" echo " specified command option," echo " Where option ls"
echo " -l Convert to lowercase"
echo " -uConvert to uppercase"
echo " The original file(s) ls not touched. A new file(s)"
echo "will be created with either a. UC or. LC extension"
echo "usage; $0 -[l|u] file [file..]"
exit 0
;;
-*) echo "usage: `basename $0` -[l|u] file [file..]"
exit 1
;;
*) # сбор файлов для обработки
if [ -f $1]
then
# добавьте имена файлов в список переменных
FILES=$FILES" "$1
else
echo "`basename $0`: Error cannot find the file $1"
fi
shift
;;
esac
done
# опции не заданы… помогите пользователю
if [ "$OРТ"="no" ]
then
echo "`basename $0`: Error you need to specify an option. No action taken"
echo " try `basename $0` --help"
exit 1
fi
#просмотр всех файлов
#используется переменная LOOP, такое красивое слово LOOP
for LOOP in $FILES
do
case $TRCASE in
lower) cat $LOOP | tr "[a?z]" "[A?Z]" >$LOOP$EXT
if [ $? != 0 ]
then
error_msg $LOOP
else
echo "Converted file called $LOOP$EXT"
fi
;;
upper} cat $LOOP|tr "[A?Z]" "[a?z]" >$LOOP$EXT
if [ $? != 0 ]
then
error_msg $LOOP
else
echo "Converted file called $LOOP$EXT"
fi
;;
esac
done
Если выполнять указанный сценарий с различными опциями в качестве входных данных, получим следующие результаты.
При передаче имени несуществующего файла:
$ tr_case -k cursor
usage: shiftl -[l|u] file [file..}
При передаче некорректных опций:
$ tr_case cursor
tr case:Error you need to specify an option. No action taken try tr_case -help
Если просто указать имя файла в надежде на ответную помощь сценария, результатом будет:
$ tr_case
For more info try tr_case -help
Если указать два имени существующих файлов, а третье — имя несуществующего файла, получим следующие результаты:
$ tr_case -l cursor sd ascii
tr case: Error cannot find the file sd
Converted file called cursor.LC
Converted file called ascii.LC
С помощью указанного сценария можно осуществить преобразование к одному и тому же регистру символов из нескольких файлов. Сценарий, который сможет обрабатывать различные опции командной строки, будет иметь большой размер.
Предположим, что существует сценарий, выполняющий обработку различных опций командной строки:
command -1 -с 23 -v файл1 файл2
Здесь нельзя применить команду shift; вместо нее следует воспользоваться командой getopts.