Одно из изменений, которые можно внедрить уже сейчас, касается включения поддержки дат в форматах MM/DD/YYYY и MM-DD-YYYY, для чего достаточно добавить следующий код непосредственно перед первым условным оператором:
if [$# −eq 1]; then # Чтобы компенсировать форматы с / и -
··set −$(echo $1 | sed 's/[\/\-]/ /g')
fi
С этим изменением сценарий позволяет вводить и нормализовать даты в следующих распространенных форматах:
$ normdate 6-10-2000
Jun 10 2000
$ normdate March-11-1911
Mar 11 1911
$ normdate 8/3/1962
Aug 3 1962
Если вы прочитаете код очень внимательно, то заметите, что в нем можно также усовершенствовать проверку поля с номером года, не говоря уже о поддержке разных международных форматов представления дат. Мы оставляем это вам как упражнение для самостоятельных исследований!
Программисты часто допускают типичную ошибку, отображая результаты вычислений без предварительного форматирования. Пользователям сложно определить, например, сколько миллионов содержится в числе 43 245 435, не подсчитав количество цифр справа налево и не добавив мысленно запятые после каждого третьего знака. Сценарий в листинге 1.7 выводит большие числа в удобочитаемом формате.
Листинг 1.7. Сценарий nicenumber форматирует большие числа, делая их удобочитаемыми
··#!/bin/bash
··# nicenumber — Отображает переданное число в формате представления с запятыми.
··#·· Предполагает наличие переменных DD (decimal point delimiter — разделитель
··#·· дробной части) и TD (thousands delimiter — разделитель групп разрядов).
··#·· Создает переменную nicenum с результатом, а при наличии второго аргумента
··#·· дополнительно выводит результат в стандартный вывод.
··nicenumber()
··{
····# Обратите внимание: предполагается, что для разделения дробной и целой
····#·· части во входном значении используется точка.
····#·· В выходной строке в качестве такого разделителя используется точка, если
····#·· пользователь не определил другой символ с помощью флага −d.
····integer=$(echo $1 | cut −d. -f1) # Слева от точки
····decimal=$(echo $1 | cut −d. -f2) # Справа от точки
····# Проверить присутствие дробной части в числе.
····if ["$decimal"!= "$1"]; then
······# Дробная часть есть, включить ее в результат.
······result="${DD:= '.'}$decimal"
····fi
··thousands=$integer
··while [$thousands −gt 999]; do
····remainder=$(($thousands % 1000)) # Три последние значимые цифры
····# В 'remainder' должно быть три цифры. Требуется добавить ведущие нули?
····while [${#remainder} −lt 3]; do # Добавить ведущие нули
······remainder="0$remainder"
····done
····result="${TD:=","}${remainder}${result}" # Конструировать справа налево
····thousands=$(($thousands / 1000)) # Оставить остаток, если есть
··done
··nicenum="${thousands}${result}"
··if [! -z $2]; then
····echo $nicenum
··fi
}
DD="." # Десятичная точка для разделения целой и дробной части
TD="," # Разделитель групп разрядов
# Начало основного сценария
# =================
··while getopts "d: t: " opt; do
····case $opt in
······d) DD="$OPTARG";;
······t) TD="$OPTARG";;
····esac
··done