【问题标题】:Check if date is in required format or not using shell script检查日期是否为所需格式或不使用 shell 脚本
【发布时间】:2021-07-08 12:15:52
【问题描述】:

我有一个制表符分隔文件,其中包含第 2、3、12 和 13 列作为日期。 我想确保这些日期是否采用这种格式 - mm/dd/yyyy,如果它们不是这种格式,我想停止该过程并以 1 退出。我能够找到一种方法来做到这一点但首先我必须将列中的每个日期传递给一个函数,而不是这样做,我宁愿使用 awk 命令。

同样,文件中的其他列是字符数据类型,它们的最大长度需要为 40。所以,我必须检查它们是否超过该长度,然后进程也应该停止。

任何帮助将不胜感激。

【问题讨论】:

  • I see你加入这个论坛已经一年半了,之前已经问过5个问题,所以你现在应该已经知道了,但是-请edit你的问题提供minimal reproducible example 具有简明、可测试的样本输入和预期输出,并展示您自己解决问题的尝试,以便我们为您提供帮助。如果不清楚,请参阅How to Ask
  • 我会使用具有适当日期日期类型的语言来进行验证。 Shell 或 awk 可以验证您的字符串是否具有适当的数字位数和/s,以正确的顺序,但它变得更狡猾。 13/0/2021 是有效日期吗? 03/30/2021 是但 02/30/2021 不是,等等。
  • @chepner 好点。 GNU awk 有 mktime() 但它会尝试找出你的意思而不是丢弃无效的日期,例如给定mktime("2021 02 30 0 0 0"),它会将该无效日期视为您编写mktime("2021 03 02 0 0 0"),因此验证日期的方法是执行date="2021 02 30"; secs=mktime(date" 0 0 0"); if ( date == strftime("%F",secs) ) it was valid; else it wasnt,即先将日期转换为纪元秒,然后将纪元秒转换为日期,如果结果日期等于原始日期,则它是有效日期。
  • 03/30/2021 真的是一个有效的日期吗?也许30/03/2021 是有效的,而03/30/2021 不是。本地化是一个非常重要的问题!

标签: shell awk


【解决方案1】:

正如chepner's comment 所指出的,使用能够识别日期并验证日期是否有效的语言非常重要。如果你想使用 shell 脚本,你可以在 bash 中使用date

#!/usr/bin/env bash
while IFS=$'\t' read -r -a array; do
  for i in 2 3 11 12; do date -d "${array[i-1]}" > /dev/null || exit 1; done
done < "$1"

但是,如果您必须处理大文件,这不是很实用,因为它需要多次调用额外的可执行文件。 GNU awk 具有时间处理能力。正如Ed Morton 's comment 所指出的那样,验证正确的时间有点棘手。函数mktime 对日期进行加法处理:

$ awk 'BEGIN{
         print strftime(mktime("2000 01 01 0 0 0"),"%F")
         print strftime(mktime("2000 01 32 0 0 0"),"%F")
         print strftime(mktime("2000 01 -1 0 0 0"),"%F")
         print strftime(mktime("2000 13 01 0 0 0"),"%F")
       }'
2000-01-01                                                                                                                                                                                                                                    
2000-02-01                                                                                                                                                                                                                                    
1999-12-30                                                                                                                                                                                                                                    
2001-01-01

所以要验证你的日期,你必须检查输入格式是否等于输出格式:

$ awk 'function cvt_time(d) {
           return strftime( "%d/%m/%Y", mktime(substr(d,7,4)" "substr(d,4,2)" "substr(d,1,2)" 0 0 0") )
       }
       BEGIN{FS="\t"}
       ($2  != cvt_time($2) ) { exit 1 }
       ($3  != cvt_time($3) ) { exit 1 }
       ($12 != cvt_time($12)) { exit 1 }
       ($13 != cvt_time($13)) { exit 1 }' file

【讨论】:

    猜你喜欢
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2011-10-06
    • 2020-08-08
    • 1970-01-01
    • 2021-10-01
    相关资源
    最近更新 更多