从 shell 脚本中的字符串中提取日期字段的更可靠方法

More robust way of extracting date field from string in shell script

我有一个描述我帐户的活动目录到期日期的字符串。我想 use/parse 这个字符串并在到期日期即将到来时做一些事情。现在我在提取完整字符串的日期部分时遇到问题。字符串是:

Password expires             1-4-2015 15:41:05

我想从中提取 1-4-2014,但是当日期为 20-12-2015 时,该机制应该也可以工作。不幸的是,我无法配置源系统以使其输出前导零。我已经尝试将字符串传送到 cut -c30-39,但显然这不适用于总长度较长的字符串(如 20-12-2015)。

所以我正在寻找更强大的解决方案,比如提取直到第二个 - 字符后的最后 4 位数字。

你可以使用 grep,

$ echo 'Password expires             1-4-2015 15:41:05' | grep -o '\b[0-9]\{1,2\}-[0-9]\{1,2\}-[0-9]\{4\}\b'
1-4-2015
$ echo 'Password expires             20-12-2015 15:41:05' | grep -o '\b[0-9]\{1,2\}-[0-9]\{1,2\}-[0-9]\{4\}\b'
20-12-2015

只查询年份。

$ echo 'Password expires             20-12-2015 15:41:05' | grep -oP '^(?:[^-]*-){2}\K\d{4}\b'
2015

只得到一天

$ echo 'Password expires             1-4-2015 15:41:05' | grep -oP '\b[0-9]{1,2}(?=-[0-9]{1,2}-[0-9]{4}\b)'
1

只获取月份

$ echo 'Password expires             1-4-2015 15:41:05' | grep -oP '\b[0-9]{1,2}-\K[0-9]{1,2}(?=-[0-9]{4}\b)'
4

或者:

awk "{print }" 

tr -s ' ' | cut -d ' ' -f 3

这是假设您在 "third thing" 之后。然后用date解析,验证。不幸的是,因为它不明确,所以您的日期字符串不会被解析。

您需要将其反转 - date 的某些版本具有 -f 输入格式说明符,但并非全部。 (我很确定如果你使用 Perl,Time::Piece 和 strptime,你也可以这样做,但怀疑这超出了范围)

date -d "2015-1-4 15:41:05" +"%s"
#1420386065

然后您可以将其与 date +"%s" 进行数字比较,以检查它的到来时间。您可以使用 cutawk 来提取日期字段。

NEWDATE=`echo $MYDATE | awk -F- '{print "-""-"}'`
date -d "$NEWDATE $TIME" +"%s"

串在一起可能会变成这样:

STRING="Password expires             1-4-2015 15:41:05"

DATE=`echo $STRING | awk '{print }'`
TIME=`echo $STRING | awk '{print }'`

NEWDATE=`echo $DATE | awk -F- '{print "-""-"}'`

EPOCH_EXP=`date -d "$NEWDATE $TIME" +"%s"`
EPOCH_TIME=`date +"%s"`

EXPIRES_S=$(($EPOCH_TIME - $EPOCH_EXP))
echo "Password expires in $EXPIRES_S seconds"

(我相信这可以做得更好,但这主要是为了说明)

两个样本没有正则表达式:

$ echo "Password expires             1-4-2015 15:41:05"  | tr -s " " | cut -d' ' -f3
1-4-2015

$ echo "Password expires             20-4-2015 15:41:05"  | tr -s " " | cut -d' ' -f3
20-4-2015