【问题标题】:Define string/timestamp match a regex in Bash script在 Bash 脚本中定义字符串/时间戳匹配正则表达式
【发布时间】:2019-08-12 12:32:30
【问题描述】:

我必须在 bash 脚本中读取文件,并在执行任何操作之前始终确认每行上的时间戳是否有效。我的时间戳如下所示:

Mar 15 14:20:48

我想检查我读取的所有时间戳是否都具有正确的格式。我尝试通过:

(date -d ...)

但这往往会过去,即使日期看起来像这样:Mar 15 14:2

有人告诉我使用正则表达式来定义日期的样子,所以我使用了这个

if [["${LASTTS}" =~ ^[a-zA-Z]+ [0-3][0-9]+ [0-2][0-9]:[0-5][0-9]:[0-5][0-9]$ ]]; then

但不断收到错误说line 38: [[Mar 15 14:20:48: command not found

【问题讨论】:

  • [[ 后面的空格不是可选的

标签: regex bash shell scripting


【解决方案1】:

假设您的格式始终与“Mar 15 14:20:48”相同(如果正确),那么它应该始终匹配 +'%b %d %T'。如果是这样,您不仅可以验证格式,还可以使用date 验证内容。

$: ts='Mar 15 14:20:48' # valid date/time in correct format
$: [[ "$ts" == "$( date +'%b %d %T' -d "$ts" )" ]] && echo ok || echo mismatch
ok
$: ts='Mar 15 14:2' # valid date/time in wrong format
$: [[ "$ts" == "$( date +'%b %d %T' -d "$ts" )" ]] && echo ok || echo mismatch
mismatch
$: ts='Feb 31 14:20:48' # invalid date/time in correct format
$: [[ "$ts" == "$( date +'%b %d %T' -d "$ts" )" ]] && echo ok || echo mismatch
date: invalid date ‘Feb 31 14:20:48’
mismatch

【讨论】:

  • 抱歉,这似乎只是对kvantour 已经提出的解决方案的另一个说明,但这样做很有趣。 :)
  • 一个小警告 - 如果运行在前一年的闰日创建的文件,这将失败,我认为......但这只是时间戳格式的一个弱点,如果非闰年不运行。
【解决方案2】:

我相信要求date 转换为预期格式并检查输入日期格式和输出日期格式是否相同可能更容易。如果它们相同,则输入日期字符串是有效字符串:

如果您使用以下命令,它会将字符串转换为您的有效格式:

date -d "input-date" "+%b %d %T"
  • 在不可能的输入日期将返回一个空字符串:
  • 无效的输入日期将返回不同的字符串

例子”

input-date (d1) | output-date (d2)| d1 == d2 | input valid
----------------+-----------------+----------+-------------
Mar 15 14:02:15 | Mar 15 14:02:15 | yes      | yes
Mar 15 14:2     | Mar 15 14:02:00 | no       | no
Mar 32 14:02:15 |                 | no       | no
Mak 15 14:02:15 |                 | no       | no
Mar 15 24:02:15 |                 | no       | no

所以你的测试看起来像:

d1="Mar 15 14:20:48"
d2=$(date -d "$d1" "+%b %d %T" 2> /dev/null)
if [[ "$d1" == "$d2" ]]; then
   echo "the dates are the same"
fi

此方法比使用正则表达式更安全,因为许多字符串可能通过正则表达式但不是有效日期。一个简单的例子是“XYZ 39 29:59:12”

如果是 OP 的问题,它将显示为:

if [[ "${LASTTS}" == $(date -d "${LASTTS}" "+%b %d %T" 2> /dev/null) ]]; then

【讨论】:

  • 如何检查它是否是有效的时间戳格式?我尝试在 3 月 15 日 14:2 通过,它仍然有效?
  • @JJAdams 你的陈述是不可能的。作为字符串"Mar 15 14:2" is different from "Mar 15 14:02:00" (the latter is the outcome of date`,第一个作为输入)。
  • 在我传入 "Mar 15 14:2" 并回显 d2 的输出后它看起来像这样: Mar 15 14:02:00 这是一个有效的时间戳,但从文件中读取了什么不是。这里的重点不是将它们相互匹配,而是确保它的格式有效,即 Month Day Hr:Min:Sec
  • @JJAdams 没错,这就是您执行检查的原因。如果“Mar 15 14:2”与d2 中存储的字符串不同,您就知道输入日期的格式错误。这是因为您特别要求以正确的格式放置它。如果输入字符串已经是正确的,那么这将是一对一的操作并且它们是相同的。
  • @JJAdams 我已对其进行了一些更新,希望使其更清晰。我的想法是 not 将输入字符串转换为有效字符串并使用后者,我的想法是进行转换以检查它是否为有效字符串。
猜你喜欢
  • 2013-08-06
  • 2011-10-17
  • 1970-01-01
  • 2016-10-22
  • 1970-01-01
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多