使用正则表达式解析SQL文件名中的日期时间戳

3

我正在编写一个用于备份数据库的bash脚本。我已经设置了一个cron作业来每天运行此脚本,并且我已经可以按照以下格式转储.sql文件:

YYYYMMDD_HHMMSS-databasename.sql

考虑到时间戳格式的名称,我想编写另一个bash脚本来解析YYMMDD文件名部分,并选择上周的所有日常文件。这个新的bash脚本将每周运行一次。

如何使用正则表达式将这些数字解析为日期?

4个回答

2

这里提供一个完整的解决方案,尝试按照以下步骤操作:

不使用正则表达式,而是使用偏移截取(假设您的示例文件格式与所有文件相同,就像在 crontab 中运行脚本一样):

cd /path/to/dumps
str='20130321_145907-databasename.sql'
for i in {7..14}; do
    curfile=$(date -d ${str:0:8} -d "$i days ago" '+%Y%m%d')*
    if [[ -s $curfile ]]; then
        # do something with "$curfile"
    fi
done

如果您真的需要使用正则表达式(regex):
cd /path/to/dumps
str='20130321_145907-databasename.sql'
if [[ $str =~ ^([0-9]{8})_[0-9]{6} ]]; then
    for i in {7..14}; do
        curfile=$(date -d ${BASH_REMATCH[1]} -d "$i days ago" '+%Y%m%d')*
        if [[ -s $curfile ]]; then
            # do something with "$curfile"
        fi
    done
fi

注意

  • 请注意curfile=行末尾的通配符*

2
从文件名中使用正则表达式选择日期部分:
^(20[12]\d)(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])_\d+-\w+\.sql$

这里解释了正则表达式:http://regex101.com/r/iU7wL5

更新 还包括正确的时间验证

^(20[12]\d)(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])_([01]\d|2[0-3])[0-5]\d[0-5]\d-\w+\.sql$

解释演示:http://regex101.com/r/yV1dD7

注意:该方法适用于2010-2029年的日期,并验证文件名是否符合输出格式。


1

使用bash 3+:

$ file=20130321_foo.log
$ [[ $file =~ ^[0-9]{8} ]]
$ echo ${BASH_REMATCH[0]}
20130321
$

他想选择每日文件,但这并没有太大帮助。请尝试完成它。 - Mostafa Shahverdy
OP的问题是“如何使用正则表达式将这些数字解析为日期?”听起来他知道当他知道如何获取yyyymmdd部分时如何完成剩余的工作。 :) - pynexj

0

这个怎么样?

LAST_WEEK_BEG=$(date --date="-7 days" +%Y%m%d)
LAST_WEEK_END=$(date --date="-14 days" +%Y%m%d)


if [ $YOUR_DATE -ge "$LAST_WEEK_BEG" ] && [ $YOUR_DATE -le "$LAST_WEEK_END" ]; then
   do things
fi

请完善KlarKW的答案 ;) - Mostafa Shahverdy
-1 用于解析 lsls 是一个交互式查看文件信息的工具。它的输出格式适合人类阅读,但会导致脚本出错。了解原因:http://mywiki.wooledge.org/ParsingLs - Gilles Quénot
@fedorqui:你看到我的回答了吗? - Gilles Quénot
1
当然了,@sputnick我做到了,并且喜欢它。无论如何,解析"ls"有什么不好的呢?好的,现在我看到你更新了你的第一个评论。 - fedorqui
这是一篇有趣的文章。由于我不想从你的帖子中复制,所以我只是回滚到我的第一个答案,其中考虑了上周的限制,因此我认为你可以取消投反对票,@sputnick。很高兴知道关于ls的这个问题! - fedorqui

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接