Календарь в одну строку

Я пытаюсь манипулировать командой cal для вывода в одну строку даты и чуть ниже дня недели, чтобы я мог использовать ее в excel для скрипта или html. Например.

Wed Thu Fri Sat Sun Mon Tue Wed
 1   2   3   4   5   6   7   8
0
07.02.2017, 12:02
4 ответа

Использование bash (или ksh93 ), и GNU date :

for (( i = 0; i < 8; ++i )); do
    printf '%s\t' "$( date -d "now +$i days" +"%a" )"
done

echo

for (( i = 0; i < 8; ++i )); do
    printf ' %d\t' "$( date -d "now +$i days" +"%e" )"
done

echo

Формат % a даст вам сокращенный день недели в текущей локали, а % e даст вам день месяц как целое число.

Результат (разделенные табуляцией):

Tue     Wed     Thu     Fri     Sat     Sun     Mon     Tue
 7       8       9      10      11      12      13      14

ОБНОВЛЕНИЕ для ksh93 после комментариев: (обратите внимание, это не работает, поскольку оболочка не проверяет даты должным образом)

#!/bin/ksh93

yearmonth=$( date +"%Y%m" )

d=1
while printf '%(%a)T\t' "$( printf '%s%02d' "$yearmonth" "$d" )" 2>/dev/null
do
    (( ++d ))
done
echo

days_this_month=$(( --d ))
while (( d > 0 )); do
    printf ' %d\t' "$(( days_this_month - (--d) ))"
done
echo

yearmonth сначала устанавливается текущий год и месяц в формате YYYYMM . Затем я перебираю все будние дни этого месяца. Цикл устанавливает wday как сокращенный день недели, и он завершается, когда я пытаюсь получить день недели для недействительной даты.

Второй цикл просто печатает целые числа, столько, сколько нам нужно, чтобы заполнить месяц.

Вывод за февраль 2017 г .:

Wed     Thu     Fri     Sat     Sun     Mon     Tue     Wed     Thu     Fri     Sat     Sun     Mon     Tue     Wed     Thu     Fri     Sat     Sun     Mon     Tue     Wed     Thu     Fri     Sat     Sun     Mon     Tue
 1       2       3       4       5       6       7       8       9       10      11      12      13      14      15      16      17      18      19      20      21      22      23      24      25      26      27      28

Решение с использованием ksh93 с Perl и Date :: Calc :

#!/bin/ksh93

ym=( $(date +"%Y %m") )

days=$( perl -MDate::Calc -e 'print Date::Calc::Days_in_Month($ARGV[0],$ARGV[1])' -- "${ym[0]}" "${ym[1]}" )

for d in {1..$days}; do
    printf '%(%a)T\t' "$( printf '%d-%d-%02d' "${ym[@]}" "$d" )"
done
echo

for d in {1..$days}; do
    printf '%d\t' "$d"
done
echo
1
28.01.2020, 02:46

только с zsh (только встроенные модули):

#! /bin/zsh -
zmodload zsh/datetime
now=$EPOCHSECONDS
strftime -s year %Y $now
strftime -s month %m $now
strftime -rs s %Y,%m,%d,%H $year,$month,1,12
output=()
while
  for field (a d m) strftime -s $field %-$field $s
  ((month == m))
do
  output+=($a $((d)))
  ((s += 86400))
done
print -C $(($#output / 2)) $output

только с bash (4.2 или выше) (только встроенные модули), но при условии, что аббревиатуры дней недели состоят из 3 символов или меньше и состоят из однобайтовых символов только в вашей локали (поэтому не будут работать правильно во многих локалях, кроме английской).

#! /bin/bash -
printf -v now '%(%s)T' -1

printf -v d '%(%-d)T' "$now"
printf -v h '%(%-H)T' "$now"
printf -v month '%(%-m)T' "$now"

s=$((now +(12-h)*3600 - (d-1) * 86400))

l1= l2=

while
  for field in a d m; do printf -v "$field" "%(%-$field)T" "$s"; done
  ((month == m))
do
  printf -v l1 '%s%-3s ' "$l1" "$a"
  printf -v l2 '%s%-3s ' "$l2" "$d"
  ((s += 86400))
done
printf '%s\n' "$l1" "$l2"
1
28.01.2020, 02:46

Вы также можете просто извлечь соответствующие строки непосредственно из cal выводит следующее:

>cal|sed -n '2p;/_/p'
Su Mo Tu We Th Fr Sa  
 5  6  7  8  9 10 11

(но обратите внимание, что cal будет использовать двухбуквенные сокращения дней недели, по крайней мере, в моей системе)

0
28.01.2020, 02:46
$ cal | perl -0ne '
   if(/(.*)(Su.*?)\n(\h*)( 1.*?)\s*$/s){
      $s= length($3); 
      $b=$2 x 5; 
      $n= $4 =~ s/[^\d ]//gr; 
      print substr($b,$s,length($n)),"\n$n\n" }'

We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu
 1  2  3  4   5  6  7  8  9 10 11  12 13 14 15 16 17 18  19 20 21 22 23 24 25  26 27 28

Объяснение: вывод cal делится на регулярное выражение (. *) (Su. *?) \ N (\ h *) (1. *?)

 Febr 2017  \nSu Mo Tu We Th Fr Sa  \n          1 2 3 4 \n 5 6 7 8 9 10 11 ...
($1         )($2                   )  ($3     )($4                         ... )

  • Используется $ 2 для построения полосы недель ( $ b = $ 2 x 5 )
  • $ 4 используется для построения списка дней после удаления \ n и выделения символов ( $ n = $ 4 = ~ s / [^ \ d] // gr )
  • длина $ 3 используется для удаления дней последнего месяца из полоса недель ( substr ($ b, $ s, length ($ n)) )
0
28.01.2020, 02:46

Теги

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