Один из аргументов , что мой сценарий получает это дата в следующем формате: yyyymmdd
.
Я хочу проверить, получаю ли я правильную дату в качестве входных данных.
Как я могу это сделать? Я пытаюсь использовать регулярные выражения, такие как:[0-9]\{\8}
Ответы:
Вы можете использовать тестовую конструкцию
[[ ]]
вместе с оператором соответствия регулярного выражения,=~
чтобы проверить, соответствует ли строка шаблону регулярного выражения.Для вашего конкретного случая вы можете написать:
Или более точный тест:
То есть вы можете определить регулярное выражение в Bash, соответствующее желаемому формату. Таким образом, вы можете сделать:
где команды after
&&
выполняются, если проверка прошла успешно, и команды after||
выполняются, если проверка не удалась.Обратите внимание, что это основано на решении Алекса-Даниэля Якименко в « Проверка формата ввода даты пользователем в bash» .
В других оболочках вы можете использовать grep . Если ваша оболочка совместима с POSIX, сделайте
В рыбе , которая не соответствует POSIX, вы можете сделать
источник
grep
команду с-E
флагом.sh
,fish
или другие менее оборудованные оболочки.В bash версии 3 вы можете использовать оператор '= ~':
Ссылка: http://tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF
источник
Хороший способ проверить правильность строки: использовать команду date:
из комментария: можно использовать форматирование
источник
date -d 2017-11-14e
он вернет вт 14 ноября 05:00:00 UTC 2017, но это сломает мой сценарий.Я бы использовал
expr match
вместо=~
:Это лучше, чем принятый в настоящее время ответ об использовании,
=~
поскольку=~
он также будет соответствовать пустым строкам, что, по-моему, не должно. Предположим,badvar
что не определен, затем[[ "1234" =~ "$badvar" ]]; echo $?
дает (неправильно)0
, аexpr match "1234" "$badvar" >/dev/null ; echo $?
дает правильный результат1
.Мы должны использовать ,
>/dev/null
чтобы скрытьexpr match
«s выходное значение , которое число символов соответствует или 0 , если совпадений не найдено. Обратите внимание, что его выходное значение отличается от его состояния выхода . Статус выхода равен 0, если совпадение найдено, или 1 в противном случае.Как правило, синтаксис для
expr
:Или:
где
$lead
регулярное выражение Значениеexit status
true (0), еслиlead
совпадает с ведущим фрагментомstring
(есть имя для этого?). Например,expr match "abcdefghi" "abc"
выходитtrue
, ноexpr match "abcdefghi" "bcd"
выходитfalse
. (Благодарю @Carlo Wood за указание на это.источник
=~
не соответствует пустым строкам, в приведенном вами примере вы сопоставляете строку с пустым шаблоном . Синтаксис естьstring =~ pattern
, и пустой шаблон соответствует всему.expr match "abcdefghi" "^" && echo Matched || echo No match
- иexpr match "abcdefghi" "bcd" && echo Matched || echo No match
- оба возвращаются"0\nNo match"
. Куда как совпадение"a.*f"
вернется"6\nMatched"
. Поэтому использование «^» в вашем примере также не нужно и уже подразумевается.=~
сопоставления пустых строк. Это то, что это поведение может быть неожиданным и может привести к ошибкам. Я написал этот ответ специально, потому что я был сожжен этим.expr
согласен со мной.В тех случаях, когда использование регулярного выражения может быть полезным для определения правильности последовательности символов даты, его нельзя легко определить, является ли дата действительной. Следующие примеры передают регулярное выражение, но все они являются недопустимыми датами: 20180231, 20190229, 20190431
Поэтому, если вы хотите проверить
datestr
правильность формата строки даты (давайте назовем ее ), лучше всего проанализировать ееdate
и попроситьdate
преобразовать строку в правильный формат. Если обе строки идентичны, у вас есть правильный формат и действительная дата.источник