我正在寻找一种使用 R 将 cron 信息转换为时间戳列表的方法。有简单的方法吗?
给定 crontab 以及开始日期和结束日期,我想获取这两个日期期间的触发时间戳列表。
我还没有找到任何专门处理 CRON 信息的包,但也许有人已经遇到过这个问题?
谢谢
我正在寻找一种使用 R 将 cron 信息转换为时间戳列表的方法。有简单的方法吗?
给定 crontab 以及开始日期和结束日期,我想获取这两个日期期间的触发时间戳列表。
我还没有找到任何专门处理 CRON 信息的包,但也许有人已经遇到过这个问题?
谢谢
我假设您的意思是crontab(5)格式。我知道没有库解析此信息,但以下代码段应该让您开始:
splitre <- function(p, s) {
s <- as.character(s)
stopifnot(length(s) == 1)
m <- gregexpr(p, s)[[1]]
if (m[1] == -1) return(s);
return(substring(s, c(1, m + attr(m, "match.length")), c(m - 1, nchar(s))))
}
ranges <- function(desc, lo, hi, name) {
res <- integer(0)
for (range in splitre(",", desc)) {
m <- regexec("^(?:\\*|(?:(\\d+)(?:-(\\d+))?))(?:/(\\d+))?$", range)
m <- regmatches(range, m)[[1]]
m[m == ""] <- NA
m[1] <- NA
m <- as.integer(m)
if (is.na(m[2])) r <- lo:hi
else if (is.na(m[3])) r <- m[2]
else r <- m[2]:m[3]
if (!is.na(m[4])) {
stopifnot(m[4] > 0)
r <- r[rep(c(TRUE, rep(FALSE, m[4] - 1)), length.out = length(r))]
}
res <- c(res, r)
}
res <- data.frame(res)
names(res) <- name
return(res)
}
ct2df <- function(lines) {
res <- data.frame()
for (line in lines) {
if (regexpr("^ *(#|$)", line) == 1) continue
parts <- splitre(" +", line)
stopifnot(length(parts) > 5)
j <- ranges(parts[1], 0, 59, "minute")
j <- merge(j, ranges(parts[2], 0, 23, "hour"))
j <- merge(j, ranges(parts[3], 1, 31, "day.of.month"))
j <- merge(j, ranges(parts[4], 1, 12, "month"))
j <- merge(j, ranges(parts[5], 0, 6, "day.of.week"))
res <- rbind(res, j)
}
return(res)
}
print(ct2df("* 1-2,5 1-10/2 */3 1 command"))
这并不完美,因为它不会处理月份或星期几的名称,也不会处理关于月份日期与星期几的特殊情况,这需要处理的*
不仅仅是一个简单的范围。
注意:命令执行的日期可以由两个字段指定 - 月份的日期和星期几。如果两个字段都受限制(即 are not
*
),则当任一字段与当前时间匹配时,将运行该命令。例如,30 4 1,15 * 5
将导致在每个月的 1 日和 15 日以及每个星期五的凌晨 4:30 运行命令。
生成的数据帧可以转换为时间戳列表,但我还没有为此编写代码。也许其他人会,在这篇文章的基础上。简单但缓慢的方法是逐分钟迭代可能的时间戳,并为每个时间戳查看计算数据帧中的一行是否与该值匹配。更快的解决方案将每天进行迭代,使用它来计算一周中的一天和一个月中的一天,然后从匹配那一天的所有行中获取时间。