在shell脚本中从字符串中提取日期字段的更强大的方法

时间:2015-02-22 10:09:56

标签: regex bash date cut

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

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

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

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

3 个答案:

答案 0 :(得分:1)

你可以使用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

答案 1 :(得分:1)

要么:

awk "{print $3}" 

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

假设你正在追逐“第三件事”。然后使用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 $3"-"$2"-"$1}'`
date -d "$NEWDATE $TIME" +"%s"

串联在一起可能最终会出现这样的事情:

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

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

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

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

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

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

答案 2 :(得分:0)

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

$ 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