Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание - страница 13
Хотите потребовать, чтобы ввод содержал только буквы верхнего регистра, пробелы, запятые и точки? Просто измените шаблон подстановки в строке
>sed 's/[^[: upper: ],]//g'
Эту же функцию можно использовать для простейшей проверки телефонных номеров (допускается присутствие цифр, пробелов, круглых скобок и дефисов, но не допускается наличие пробелов в начале или нескольких пробелов, идущих подряд), если использовать шаблон:
>sed 's/[^- [: digit: ]\(\)]//g'
Но, если нужно ограничить ввод целыми числами, опасайтесь ловушки. Например, на первый взгляд кажется, что следующий шаблон справится с этой задачей:
>sed 's/[^[: digit: ]]//g'
Однако он будет пропускать только положительные целые числа. А что, если вам необходимо разрешить ввод отрицательных чисел? Если вы просто добавите знак «минус» в множество допустимых символов, функция признает допустимой строку -3–4, хотя совершенно очевидно, что она не является допустимым целым числом. Обработка отрицательных чисел демонстрируется в сценарии № 5.
№ 3. Нормализация форматов дат
Разработчикам сценариев часто приходится иметь дело с большим количеством разнообразных форматов представления дат, нормализация которых может быть сопряжена с разными сложностями. Самые серьезные проблемы связаны с датами, потому что они записываются самыми разными способами. Даже если потребовать ввести дату в определенном формате, например месяц-день-год, вы почти наверняка получите несовместимый ввод: номер месяца вместо названия, сокращенное название вместо полного или даже полное название со всеми буквами в верхнем регистре. По этой причине функция нормализации дат, даже самая простенькая, послужит очень хорошим строительным блоком для многих сценариев, особенно таких, как сценарий № 7.
Код
Сценарий в листинге 1.5 нормализует строки с датами, используя относительно простой набор критериев: месяц должен задаваться именем или числом в диапазоне от 1 до 12, а год — четырехзначным числом. Нормализованная строка с датой включает название месяца (в виде трехсимвольного сокращения), за которым следуют день месяца и четырехзначный год.
Листинг 1.5. Сценарий normdate
>··#!/bin/bash
>··# normdate — Нормализует поле месяца в строке с датой в трехсимвольное
>··#·· представление, с первой буквой в верхнем регистре.
>··#·· Вспомогательная функция для сценария № 7, valid-date.
>··#·· В случае успеха возвращает 0.
>··monthNumToName()
>··{
>····# Присвоить переменной 'month’ соответствующее значение.
>····case $1 in
>······1) month="Jan";; 2) month="Feb";;
>······3) month="Mar";; 4) month="Apr";;
>······5) month="May";; 6) month="Jun";;
>······7) month="Jul";; 8) month="Aug";;
>······9) month="Sep";; 10) month="Oct";;
>······11) month="Nov";; 12) month="Dec";;
>······*) echo "$0: Unknown month value $1" >&2
>········exit 1
>····esac
>····return 0
>··}
>··
>··# НАЧАЛО ОСНОВНОГО СЦЕНАРИЯ — УДАЛИТЕ ИЛИ ЗАКОММЕНТИРУЙТЕ ВСЕ, ЧТО НИЖЕ,
>··# ЧТОБЫ ЭТОТ СЦЕНАРИЙ МОЖНО БЫЛО ПОДКЛЮЧАТЬ К ДРУГИМ СЦЕНАРИЯМ.
>··# =================
>··# Проверка ввода
>··if [$# −ne 3]; then
>····echo "Usage: $0 month day year" >&2
>····echo "Formats are August 3 1962 and 8 3 1962" >&2
>····exit 1
>··fi
>··if [$3 −le 99]; then
>····echo "$0: expected 4-digit year value." >&2
>····exit 1
>··fi
>··# Месяц введен как число?
>
>····monthNumToName $1
>··else
>··# Нормализовать до 3 первых букв, первая в верхнем регистре, остальные в нижнем.
>
>
>··fi
>··echo $month $2 $3
>··exit 0
Как это работает
Обратите внимание на третий условный оператор в этом сценарии