Конвертировать cron в метки времени в R
Я ищу способ преобразовать информацию cron в список временных меток, используя R. Есть ли простой способ сделать это?
Учитывая crontab и дату начала и дату окончания, я хотел бы получить список меток времени триггера в течение этих двух дат.
Я не нашел ни одного пакета, который бы конкретно касался информации CRON, но, возможно, у кого-то уже была эта проблема?
Спасибо
1 ответ
Я предполагаю, что вы имеете в виду формат 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"))
Это не идеально, так как он не будет обрабатывать имена в течение месяцев или дней недели, и не будет обрабатывать особый случай день месяца против дня недели, который требует обработки *
как более простой диапазон.
Примечание. День выполнения команды может быть задан двумя полями: день месяца и день недели. Если оба поля ограничены (т.е. не
*
), команда будет выполнена, когда любое из полей будет соответствовать текущему времени. Например,30 4 1,15 * 5
приведет к выполнению команды в 4:30 утра 1-го и 15-го числа каждого месяца плюс каждую пятницу.
Полученный фрейм данных можно превратить в список меток времени, но я не написал код для этого. Возможно, кто-то еще, опираясь на этот пост. Простой, но медленный метод будет перебирать возможные временные метки каждую минуту, и для каждой временной метки будет видно, соответствует ли строка из вычисленного фрейма данных этому значению. Более быстрые решения будут повторяться изо дня в день, использовать их для определения дня недели и дня месяца, а затем брать время из всех строк, соответствующих этому дню.