Нужно получить даты всех понедельников в году - PullRequest
7 голосов
/ 18 февраля 2011

Мне нужно сортировать данные еженедельно, и все, что у меня есть, - это даты в лог-файле.Поэтому, чтобы отсортировать данные за неделю, я хотел бы создать список с датами всех понедельников для данного года.Я пытался что-то придумать, и единственная идея, которая у меня сейчас есть, - это использовать ncal с годом и месяцем в качестве аргумента, повторяющегося во всех месяцах и извлекающего все понедельники.Разве нет более эффективного способа?

Ответы [ 5 ]

4 голосов
/ 18 февраля 2011

Чтобы получить все понедельники, получая все даты и фильтруя по понедельникам:

for i in `seq 0 365`
    do date -d "+$i day"
done | grep Mon

Конечно, вы также можете взять понедельник и увеличивать его на 7 дней.

3 голосов
/ 18 февраля 2011

надеюсь, это то, что вы имеете в виду.Ниже можно изменить формат выходных данных дат. Для этого можно использовать команду date

, не знаю, если ncal более / менее эффективен."сейчас, но вот более читабельный v.

$ cat /tmp/1.sh
#!/bin/bash

test -z "$year" && {
    echo "I expect you to set \$year environment variable"
    echo "In return I will display you the Mondays of this year"
    exit 1
}

# change me if you would like the date format to be different
# man date would tell you all the combinations you can use here
DATE_FORMAT="+%Y-%m-%d"

# change me if you change the date format above. I need to be
# able to extract the year from the date I'm shoing you
GET_YEAR="s/-.*//"

# this value is a week, in milliseconds. Changing it would change
# what I'm doing.
WEEK_INC=604800

# Use another 3-digit week day name here, to see dates for other week days
DAY_OF_WEEK=Mon

# stage 1, let's find us the first day of the week in this year

d=1
# is it DAY_OF_WEEK yet?
while test "$(date -d ${year}-1-${d} +%a)" != "$DAY_OF_WEEK"; do
# no, so let's look at the next day
    d=$((d+1));
done;

# let's ask for the milliseconds for that DAY_OF_WEEK that I found above
umon=$(date -d ${year}-1-${d} +%s)

# let's loop until we break from inside
while true; do
   # ndate is the date that we testing right now
   ndate=$(date -d @$umon "$DATE_FORMAT");
   # let's extract year
   ny=$(echo $ndate|sed "$GET_YEAR");
   # did we go over this year? If yes, then break out
   test $ny -ne $year && { break; }
   # move on to next week
   umon=$((umon+WEEK_INC))
   # display the date so far
   echo "$ndate"
done
2 голосов
/ 29 декабря 2011

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

#!/bin/bash

datestart=20110101
dateend=20111231

for tmpd in {0..6}
do
  date -d "$datestart $tmpd day" | grep -q Mon
  if [ $? = 0 ];
  then
    break
  fi
done

for ((tmpw = $tmpd; $(date -d "$datestart $tmpw day" +%s) <= $(date -d "$dateend" +%s); tmpw += 7))
do
  echo `date -d "$datestart $tmpw day" +%d-%b-%Y`
done
2 голосов
/ 18 февраля 2011

Нет необходимости повторять все 365 или 366 дней в году.Следующее выполняет date самое большее 71 раз.

#!/bin/bash
y=2011

for d in {0..6}
do
    if (( $(date -d "$y-1-1 + $d day" '+%u') == 1))   # +%w: Mon == 1 also
    then
        break
    fi
done

for ((w = d; w <= $(date -d "$y-12-31" '+%j'); w += 7))
do
    date -d "$y-1-1 + $w day" '+%Y-%m-%d'
done

Вывод:

2011-01-03
2011-01-10
2011-01-17
2011-01-24
2011-01-31
2011-02-07
2011-02-14
2011-02-21
2011-02-28
2011-03-07
. . .
2011-11-28
2011-12-05
2011-12-12
2011-12-19
2011-12-26
1 голос
/ 18 февраля 2011

Вы можете получить номер текущей недели, используя date. Может быть, вы можете сортировать по этому:

$ date +%W -d '2011-02-18'
07
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...