Дейв Тейлор - Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание
- Название:Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание
- Автор:
- Жанр:
- Издательство:Питер
- Год:2017
- Город:СПб.
- ISBN:978-5-496-03029-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дейв Тейлор - Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание краткое содержание
Цель этой книги — продемонстрировать практические приемы программирования сценариев на bash и познакомить с самыми распространенными утилитами на коротких и компактных примерах, не вдаваясь в излишние подробности. Экспериментируйте с этими сценариями — ломайте, исправляйте и приспосабливайте их под свои нужды, чтобы понять, как они работают. Только так вы сможете решать самые сложные задачи.
Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Хотите потребовать, чтобы ввод содержал только буквы верхнего регистра, пробелы, запятые и точки? Просто измените шаблон подстановки в строке , как показано ниже:
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
··# Месяц введен как число?
··if [-z $(echo $1|sed 's/[[: digit: ]]//g')]; then
····monthNumToName $1
··else
··# Нормализовать до 3 первых букв, первая в верхнем регистре, остальные в нижнем.
····month="$(echo $1|cut −c1|tr '[: lower: ]' '[: upper: ]')"
····month="$month$(echo $1|cut −c2-3 | tr '[: upper: ]' '[: lower: ]')"
··fi
··echo $month $2 $3
··exit 0
Как это работает
Обратите внимание на третий условный оператор в этом сценарии . Он выбрасывает из поля с месяцем все цифры и затем с помощью оператора −z проверяет, получилась ли в результате пустая строка. Если получилась, это означает, что в поле содержатся только цифры, соответственно, его можно напрямую преобразовать в название месяца вызовом функции monthNumToName, которая дополнительно проверяет номер месяца на попадание в диапазон от 1 до 12. Иначе предполагается, что первое поле во введенной строке содержит название месяца, которое нормализуется сложной последовательностью команд cut и tr с использованием двух подоболочек (то есть последовательности команд заключены в скобки $(и), которые вызывают заключенные в них команды и возвращают их вывод).
Первая последовательность команд в подоболочке, в строке , извлекает первый символ из поля с названием месяца и с помощью tr преобразует его в верхний регистр (последовательность echo $1|cut −c1 можно также записать в стиле POSIX: ${1 %${1#?}}, как было показано выше). Вторая последовательность, в строке
, извлекает второй и третий символы и преобразует их в нижний регистр. В результате получается трехсимвольное сокращенное название месяца с первым символом в верхнем регистре. Обратите внимание, что в данном случае не проверяется — содержит ли исходное поле допустимое название месяца, в отличие от случая, когда месяц задается числом.
Запуск сценария
Для максимальной гибкости будущих сценариев, использующих normdate, этот сценарий спроектирован так, что принимает исходные данные в виде трех аргументов командной строки, как показано в листинге 1.6. Если вы предполагаете использовать сценарий только интерактивно, предложите пользователю ввести дату в виде трех значений, однако это усложнит вызов normdate из других сценариев.
Результаты
Листинг 1.6.Тестирование сценария normdate
$ normdate 8 3 62
normdate: expected 4-digit year value.
$ normdate 8 3 1962
Aug 3 1962
$ normdate AUGUST 03 1962
Aug 03 1962
Обратите внимание, что этот сценарий нормализует только представление месяца; представление дня (в том числе с ведущими нулями) и года не изменяется.
Усовершенствование сценария
Прежде чем знакомиться с разными усовершенствованиями, которые можно добавить в этот сценарий, загляните в раздел с описанием сценария № 7, где используется normdate для проверки вводимых дат.
Одно из изменений, которые можно внедрить уже сейчас, касается включения поддержки дат в форматах MM/DD/YYYY и MM-DD-YYYY, для чего достаточно добавить следующий код непосредственно перед первым условным оператором:
Читать дальшеИнтервал:
Закладка: