цикл удара между двумя данными датами

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

А типичный пример - Вы, имеют Ваш пользовательский сжатый формат архива для данных по диску, и сторонняя библиотека с плохим API хочет получить доступ к данным по диску и ожидает путь к файлу, где это может загрузить свои данные.

Эта ссылка имеет некоторые положительные стороны: http://gamearchitect.net/2008/09/19/good-middleware/

9
задан Jonathan Leffler 27 October 2009 в 06:29
поделиться

3 ответа

Для обработки каждого файла между две заданные даты / часы, вы можете использовать следующее:

#!/usr/bin/bash
#set -x

usage() {
    echo 'Usage: loopscript.sh <from> <to>'
    echo '       <from> MUST be yyyymmdd.hh or empty, meaning 00000000.00'
    echo '       <to> can be shorter and is affected by <from>'
    echo '         e.g., 20091026.00       27.01 becomes'
    echo '               20091026.00 20091027.01'
    echo '         If empty, it is set to 99999999.99'
    echo 'Arguments were:'
    echo "   '${from}'"
    echo "   '${to}'"
}

# Check parameters.

from="00000000.00"
to="99999999.99"
if [[ ! -z "$1" ]] ; then
    from=$1
fi
if [[ ! -z "$2" ]] ; then
    to=$2
fi
## Insert this to default to rest-of-day when first argument
##    but no second argument. Basically just sets second
##    argument to 23 so it will be transformed to end-of-day.
#if [[ ! -z "$1"]] ; then
#    if [[ -z "$2"]] ; then
#        to=23
#    fi
#fi

if [[ ${#from} -ne 11 || ${#to} -gt 11 ]] ; then
    usage
    exit 1
fi

# Sneaky code to modify a short "to" based on the start of "from".
# ${#from} is the length of ${from}.
# $((${#from}-${#to})) is the length difference between ${from} and ${to}
# ${from:0:$((${#from}-${#to}))} is the start of ${from} long enough
#   to make ${to} the same length.
# ${from:0:$((${#from}-${#to}))}${to} is that with ${to} appended.
# Voila! Easy, no?

if [[ ${#to} -lt ${#from} ]] ; then
    to=${from:0:$((${#from}-${#to}))}${to}
fi

# Process all files, checking that they're inside the range.

echo "From ${from} to ${to}"
for file in [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].[0-9][0-9].* ; do
    if [[ ! ( ${file:0:11} < ${from} || ${file:0:11} > ${to} ) ]] ; then
        echo "   ${file}"
    fi
done

Когда вы создаете файлы с 20091026.00. $ {RANDOM} по 20091028.23. $ {RANDOM} включительно, это пара пробных прогонов:

pax> ./loopscript.sh 20091026.07 9
From 20091026.07 to 20091026.09
   20091026.07.21772
   20091026.08.31390
   20091026.09.9214
pax> ./loopscript.sh 20091027.21 28.02
From 20091027.21 to 20091028.02
   20091027.21.22582
   20091027.22.30063
   20091027.23.29437
   20091028.00.14744
   20091028.01.6827
   20091028.02.10366
pax> ./loopscript.sh 00000000.00 99999999.99 # or just leave off the parameters.
   20091026.00.25772
   20091026.01.25964
   20091026.02.21132
   20091026.03.3116
   20091026.04.6271
   20091026.05.14870
   20091026.06.28826
   : : :
   20091028.17.20089
   20091028.18.13816
   20091028.19.7650
   20091028.20.20927
   20091028.21.13248
   20091028.22.9125
   20091028.23.7870

Как видите, первый аргумент должен иметь правильный формат yyyymmdd.hh . Второй аргумент может быть короче, поскольку он наследует начало первого аргумента, чтобы сделать его правильной длиной.

Это пытается обрабатывать только файлы, которые существуют (из ls ) и имеют правильный формат, не каждую дату / час в пределах диапазона. Это будет более эффективно, если у вас есть разреженные файлы (в том числе в начале и в конце диапазона), так как не нужно проверять, существуют ли файлы.

Кстати, это команда, которая создала тест файлы, если вам интересно:

pax> for dt in 20091026 20091027 20091028 ; do
         for tm in 00 01 02 ... you get the idea ... 21 22 23 ; do
             touch $dt.$tm.$RANDOM
         done
     done

Пожалуйста, не вводите это дословно, а затем жалуйтесь, что были созданы такие файлы, как:

20091026.you.12345
20091028.idea.77

Я только обрезал строку, чтобы она соответствовала ширине кода. : -)

Не нужно проверять, существуют ли файлы.

Между прочим, это команда, которая создала тестовые файлы, если вам интересно:

pax> for dt in 20091026 20091027 20091028 ; do
         for tm in 00 01 02 ... you get the idea ... 21 22 23 ; do
             touch $dt.$tm.$RANDOM
         done
     done

Пожалуйста, не вводите это дословно, а затем жалуйтесь, что она создала файлы например:

20091026.you.12345
20091028.idea.77

Я только обрезал строку, чтобы она соответствовала ширине кода. : -)

Не нужно проверять, существуют ли файлы.

Между прочим, это команда, которая создала тестовые файлы, если вам интересно:

pax> for dt in 20091026 20091027 20091028 ; do
         for tm in 00 01 02 ... you get the idea ... 21 22 23 ; do
             touch $dt.$tm.$RANDOM
         done
     done

Пожалуйста, не вводите это дословно, а затем жалуйтесь, что она создала файлы например:

20091026.you.12345
20091028.idea.77

Я только обрезал строку, чтобы она соответствовала ширине кода. : -)

5
ответ дан 4 December 2019 в 07:35
поделиться

Как насчет этого:

#!/bin/bash

date1=$1
date2=$2

#verify dates
if ! date -d "$date1" 2>&1 > /dev/null ; 
    then echo "first date is invalid" ; exit 1
fi
if ! date -d "$date2" 2>&1 > /dev/null ; 
    then echo "second date is invalid" ; exit 1
fi

#set current and end date
current=$(date -d "$date1")
end=$(date -d "$date2 +1 hours")

#loop over all dates
while [ "$end" != "$current" ] 
do
    file=$(date -d "$current" +%Y%m%d.%H)
    cat $file."filename" | more
    current=$(date -d "$current +1 hours")
done
23
ответ дан 4 December 2019 в 07:35
поделиться

Одно из возможных решений: преобразовать даты в стандартное представление Unix «Секунды, прошедшие с эпохи» и выполнить цикл, увеличивая это число на 3600 (количество секунд в часе) на каждой итерации. Пример:

#!/bin/bash

# Parse your input to date and hour first, so you get:
date_from=20090911
hour_from=10
date_to=20091026
hour_to=01

i=`date --date="$date_from $hour_from:00:00" +%s`
j=`date --date="$date_to $hour_to:00:00" +%s`

while [[ $i < $j ]]; do
  date -d "1970-01-01 $i sec" "+%Y%m%d.%H"
  i=$[ $i +  3600 ]
done
1
ответ дан 4 December 2019 в 07:35
поделиться
Другие вопросы по тегам:

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