Выполнение функции в месяц в диапазоне дат

«Предпочтения» > «Настройки LXQt» > «Пользователи и группы»

19.04:

19.04: Preferences > LXQt settings >  Users and Groups

0
06.10.2020, 03:19
1 ответ

Такие инструменты, как dateutils , обычно лучше подходит для такой работы, но это можно сделать с помощью примитивов оболочки, здесь с другим набором параметров, чем у вас, для краткости.

#!/bin/sh
# For a date range print start and end date per calendar month.

# Gregorian calendar: number of days in month.
# $1 year (>= 1600)
# $2 month (1..12), one leading '0' allowed for 1..9
# exitval: day count (28..31)
daysinmonth() {
    case "$2" in
    (2|02)
        test 0 -eq $(($1 % 4 || !($1 % 100) && $1 % 400))
        return $((28 + ($?<1))) ;;
    (4|6|9|11|04|06|09)
        return 30 ;;
    (*) return 31 ;;
    esac
}

# Print year,month,day in ISO 8601 basic format
isobasic() {
    printf '%d%02d%02d' "$1" "$2" "$3"
}

ylo="$1" mlo="${2#0}" dlo="${3#0}"      # range start
yhi="$4" mhi="${5#0}" dhi="${6#0}"      # range end
isohi=$(isobasic "${yhi}" "${mhi}" "${dhi}")
until 
    isolo=$(isobasic "${ylo}" "${mlo}" "${dlo}")
    test $(( isolo - isohi )) -gt 0
    # test "${isolo}" \> "${isohi}"     # dash, bash
do
    # compute end of month
    daysinmonth "${ylo}" "${mlo}"
    isoeom=$(isobasic "${ylo}" "${mlo}" "${?}")
    # print start, end date for partial/whole calendar month
    test "${isoeom%??}" != "${isohi%??}" || isoeom="${isohi}"
    printf '%s%s %s\n' "${PREFIX:-}" "${isolo}" "${isoeom}"
    # increase *lo values to first of next month
    dlo=1
    : $(( mlo = (mlo == 12 ? 1 : mlo + 1) ))
    : $(( ylo = (mlo > 1 ? ylo : ylo + 1) ))
done
# fail if start later than end date
return $(( isoeom == isohi ? 0 : 1 ))

Дана команда

PREFIX='cmd './script 2016 11 09 2020 3 5

вывод:

cmd 20161109 20161130
cmd 20161201 20161231
cmd 20170101 20170131
cmd 20170201 20170228
...
cmd 20191201 20191231
cmd 20200101 20200131
cmd 20200201 20200229
cmd 20200301 20200305
0
18.03.2021, 23:00

Теги

Похожие вопросы