Отображение числа недели в определенном формате с помощью ncal или cal

Это немного изменяется из инструкций, найденных здесь (и я даже не проверил, работают ли они):

  1. Установите chkfontpath пакет от ATrpms (Нажмите или на i686 или на x86_64 пакет, в зависимости от того, есть ли у Вас 32-разрядная или 64-разрядная машина).

  2. Как корень, установите некоторые пакеты, в которых Вы будете нуждаться для следующих шагов:

    yum install rpm-build cabextract ttmkfdir wget
    
  3. Загрузите шрифты ядра MS умный файл пакета:

    wget http://corefonts.sourceforge.net/msttcorefonts-2.0-1.spec
    
  4. Создайте Базовый пакет Шрифтов:

    rpmbuild -ba msttcorefonts-2.0-1.spec
    
  5. Установите Базовый пакет Шрифтов:

    yum install --nogpgcheck /root/rpmbuild/RPMS/noarch/msttcorefonts-2.0-1.noarch.rpm
    

15
30.11.2016, 17:04
11 ответов
[118131] Если ни одна из этих команд не подходит вам, вы можете использовать [118544]gcal[118545], чтобы сделать то, что вы хотите.

Пример

Печатает номер недели в последнем столбце справа.

Ссылки[12130]Gcal the ultra-power command line GNU calendar[12131]Gcal user's manual[12132]The many use of gcal[12133]
13
27.01.2020, 19:49

Это выделяет сегодняшнюю дату и может отобразить любой месяц через $1 в форме: YYYY-mm-dd ... Это принимает значение по умолчанию на сегодняшнюю дату

Это настраивается для показа недельных чисел ISO, и первый рабочий день, будучи понедельником.

#!/bin/bash
# Input reference date is expected in  'YYYY-mm-dd' format
#
today=($(date '+%Y %m %d')); Y=0; m=1; d=2                # establish today's date
[[ -z $1 ]] && ref=(${today[@]}) || ref=(${1//-/ })       # get input date
dNbA=$(date --date="$(date +%Y-%m-01)" +'%u')             # day-number of 1st day of reference month
today[m]=$((10#${today[m]})); ref[m]=$((10#${ref[m]}))    # remove leading zero (octal clash)
today[d]=$((10#${today[d]})); ref[d]=$((10#${ref[d]}))    # remove leading zero (octal clash)
nxtm=$(( ref[m]==12 ?1       :ref[m]+1 ))                 # month-number of next month
nxtY=$(( ref[m]==12 ?ref[Y]+1:ref[Y]   ))                 # year-number of next month
nxtA="$nxtY-$nxtm-1"                                      # date of 1st day of next month
refZ=$(date --date "$(date +$nxtA) yesterday" +%Y-%m-%d)  # date of last day of reference  month
days=$(date --date="$refZ" '+%d')                         # days in reference month

h1="$(date --date="${ref[Y]}-${ref[m]}-${ref[d]}" '+%B %Y')" # header 1 
h2="Mo Tu We Th Fr Sa Su"                                    # header 2 
printf "    %$(((${#h2}-${#h1}-1)/2))s%s\n" " " "$h1"
printf "    %s\n" "$h2"
# print week rows   
printf "%2d  " "$((10#$(date -d "$(date +${ref[Y]}-${ref[m]}-01)" +'%V')))" # week-number (of year) with suppressed leading 0
printf "%$(((dNbA-1)*3))s"  # lead spaces (before start of month)
dNbW=$dNbA  # day-number of week
dNbM=1      # day-number of month
while ((dNbM <= days)) ;do
    if (( today[Y]==ref[Y] &&  
          today[m]==ref[m] && 
          today[d]==dNbM )) ;then
        printf "\x1b[7m%2d\x1b[0m " "$dNbM" # highlight today's date 
    else
        printf "%2d " "$dNbM"
    fi
    ((dNbM++))
    if ((dNbW  >=7)) ;then
        cdate=$((10#$(date -d "$(date +${ref[Y]}-${ref[m]}-$dNbM)" +'%V'))) # remove leading zero (octal clash)
        printf "\n%2d  " "$cdate" # week-number of year
        dNbW=0
    fi
    ((dNbW++))
done
printf "%$(((8-dNbW)*3))s\n" # trailing spaces (after end of month)

Вот дисплей этого месяца (с 20 выделенный)

       January 2012
    Mo Tu We Th Fr Sa Su
52                     1 
 1   2  3  4  5  6  7  8 
 2   9 10 11 12 13 14 15 
 3  16 17 18 19 20 21 22 
 4  23 24 25 26 27 28 29 
 5  30 31                
9
27.01.2020, 19:49
  • 1
    я даже не заметил изопроблему. Это сделает :) –  k0pernikus 20.01.2012, 13:18
  • 2
    @k0pernikus: я только что изменил сценарий.. (спустя приблизительно 35 минут после регистрации вышеупомянутого комментария).. Это становилось схваченным на 08 и 09 будучи интерпретируемым как восьмеричный вместо десятичного числа.. Это должно быть прекрасным теперь... –  Peter.O 20.01.2012, 14:05

Генерируйте недельную последовательность с ncal и используйте paste для того, чтобы иметь оба вывода рядом.

$ paste <(echo; echo; ncal -w | tail -1 | xargs -n1 printf '%2d\n') <(cal)

Если Вам не нравится иметь вкладки, поскольку разделители просто добавляют что-то как sed 's/\t/ /'


Править: более простой путь, никакая потребность заботиться о вкладках:

$ paste -d' ' <((echo -n '   '; ncal -w | tail -1 )| fold -w 3) <(cal)
7
27.01.2020, 19:49
  • 1
    Изящный и воплощает многие из 17 Правил Unix ESR. Должен быть принятый ответ, поскольку он действительно комбинирует вывод cal и ncal (другие подходы копируют поведение также cal или ncal). –  bishop 30.11.2016, 16:53

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

$ cal | perl -pe 'if ( m/\A\s*\d/ ) { s/\A/++$i . qq[ ] x 2/e } else { s/\A/qq[ ] x 3/e }'

Вывод:

       enero de 2012   
   lu ma mi ju vi sá do
1                     1
2   2  3  4  5  6  7  8
3   9 10 11 12 13 14 15
4  16 17 18 19 20 21 22
5  23 24 25 26 27 28 29
6  30 31

Объяснение:

-pe                     # For every input line from previous pipe, execute  next
                        # instructions and print to output.
if ( m/\A\s*\d/ )       # If line begins with a digit omitting spaces...
s/\A/++$i . qq[ ] x 2/e # Insert at the beginning of the line a counter plus two spaces.
else                    # else...
s/\A/qq[ ] x 3/e        # Insert three spaces at the beginning of the line.
4
27.01.2020, 19:49
  • 1
    , как это будет работать в течение последующих месяцев. Недели в феврале не запускаются от снова 1, они запускают от любого 5/6 так же, март будет от 9/10. –  Nikhil Mulley 19.01.2012, 12:41
  • 2
    cal 02 2012, это будет иметь отказавшим?? –  Nikhil Mulley 19.01.2012, 12:42
  • 3
    @Nikhil: Я не понимаю то, что Вы имеете в виду. Можно ли попытаться объяснить это больше подробно? Делает сбой сценария с cal 02 2012? Это, казалось, работало в моем тесте. –  Birei 19.01.2012, 12:52
  • 4
    @Nikhil: А-ч, хорошо. Я неправильно понял вопрос. Это означает абсолютные недельные числа а не относительно каждого месяца. Я удалю свой неправильный ответ в некоторое время. прохладный –  Birei 19.01.2012, 12:55
  • 5
    .. не удаляйте ответ, сохраните его для ссылки. –  Nikhil Mulley 19.01.2012, 13:09

Можно использовать nl пронумеровать строки (это - цель программы :). Но необходимо извлечь первую неделю в месяце из где-нибудь. Это может быть сделано от ncal самостоятельно:

$ ncal -w 2 2012 | tail -1 | awk '{print $1}'
5

Мы вставляем это в качестве параметра в nlопция -v (начинающий номер строки), и говорят это только числовым осям с числами или пробелами.

$ cal 2 2012 | nl -bp'^[0-9 ]\+$' -w2 -s'  ' -v$(ncal -w 2 2012 | tail -1 | awk '{print $1}')
       February 2012
    Su Mo Tu We Th Fr Sa
 5            1  2  3  4
 6   5  6  7  8  9 10 11
 7  12 13 14 15 16 17 18
 8  19 20 21 22 23 24 25
 9  26 27 28 29

Это все ужасно хрупко все же. Так или иначе, если Вы не испытываете необходимость calбольше расширенных настроек, это будет работать. Можно поместить его в файл и замену "$@" куда я поместил 2 2012.


Править: Но это НЕПРАВИЛЬНО! Я просто заметил, что первая неделя в январе может иметь номер 52 или 53! Таким образом, мы просто или должны сделать исключение на январь или просто извлечь всю неделю числа из ncal и примените их к выводу cal.

Это - решение, я думал первоначально, но я думал (ошибочно), что я упрощу его использование nl. Это использует paste, который объединяет файлы бок о бок. С тех пор нет никакого файла, мы должны использовать bashism <(...); это - то, чего я старался избегать.

Наш первый "файл" будет списком недельных чисел с двумя пустыми строками вначале:

$ printf '   \n   \n' && printf '%2d \n' $(ncal -w 1 2011 | tail -1)


52
 1
 2
 3
 4
 5

Второй, просто вывод cal. Все вместе, как параметры к paste:

$ paste -d' ' <(printf '   \n   \n' && printf '%2d \n' $(ncal -w 1 2011 | tail -1)) <(cal 1 2011)
        January 2011
    Su Mo Tu We Th Fr Sa
52                     1
 1   2  3  4  5  6  7  8
 2   9 10 11 12 13 14 15
 3  16 17 18 19 20 21 22
 4  23 24 25 26 27 28 29
 5  30 31

Намного более грязный и несовместимый, что другой. Пластина En...

7
27.01.2020, 19:49
  • 1
    Не настолько большой :-/. Посмотрите мое редактирование. –  angus 19.01.2012, 14:01

Вот мое решение, которое короче в коде и работает нормально для других дат, чем текущий месяц. Извините за людей США, это использует формат ISO, то есть 1-й день недели - понедельник. Это сделано с вариантом -m для Cal и% v для даты

#!/bin/bash
if [ "$1" = "" ]
then
  when="now"
else
  when="$1"
fi
y=$(date --date "$when" +%Y )
if [ $? -ne 0 ]
then
  exit
fi
m=$(date --date "$when" +%m )
w=$(date --date $(printf %4d%02d01 $y $m) +%V)
cal -m $m $y |
  awk -v w=$w '
    NR>2{ww=w++}
    $0!=""{printf "%2s %s\n", ww , $0}
  '
0
27.01.2020, 19:49

Я создал этот сценарий для создания дежурного календаря для команд. Он генерирует календарь с номерами недель и присваивает им имена (просто циклический). После того, как вывод напечатан, вам просто нужно скопировать его в Excel и выполнить «текст в столбец»; и еще раз выполните «текст в столбец» в первом столбце, используя параметр «фиксированный». Преимущество этого календаря (по сравнению с горизонтальной ориентацией) заключается в том, что вы можете использовать автоматический фильтр (Alt + d f f) и находить только свои недели.

#!/usr/bin/ksh
y=2017
set -A team1 Petars Justas Richard Jukka Jesper
set -A team2 Modestas Timo Mats Andreas

i1=0
i2=0
wn=1
own=1

echo "WN     Month        Mo Tu We Th Fr Sa Su ;Team1 ;Team2"
ycal=`for m in 1 2 3 4 5 6 7 8 9 10 11 12
do
IFS=
        cal -m $m $y|egrep -v "Mo|^$"|while read line
        do
                echo $line|grep -q $y && mname=$line || print $mname $line|sed 's/'$y'//'
        done
done`
IFS=
echo "$ycal"|while read line2
do
IFS=
        echo "$line2"|grep -v "1  2  3  4  5  6  7"|egrep -q "* 1 |* 1$" || let wn++
        [ $own -ne $wn ] && { \
                [ $i1 -eq ${#team1[@]}-1 ] && i1=0 || let i1++;\
                [ $i2 -eq ${#team2[@]}-1 ] && i2=0 || let i2++; }
        printf '%2s %s ;%s ;%s\n' $wn $line2 ${team1[$i1]} ${team2[$i2]}
        own=$wn
done

Извините, код немного неприятный ... и без комментариев ... но работает хорошо;)

0
27.01.2020, 19:49

Без достаточного количества представителей, чтобы прокомментировать ответ от slm, gcal можно установить в Mac OS, используя brew install gcal.

(Сначала я нашел ответ здесь, затем этот ответ на другом вопросе, но в ответе unix не было всей информации, необходимой для установки на Mac.)

1
27.01.2020, 19:49

Мне не очень хочется устанавливать gcal, и мне не удалось заставить его работать должным образом в моей системе. Таким образом, без gcalответ funolletдействительно является лучшим решением. Я только немного изменил его, чтобы он также сохранил форматирование, такое как деньвыделение , цвета и т. д. с помощью команды script. Я также удалил лишние символы, сделав его пригодным для использования в качестве псевдонима как такового :

.
alias today="paste -d' ' <((echo ' '{,};ncal -w|tail -1)|fold -w3) <(script /dev/null -qc cal)"

Или замените calновой функцией. Однако с этим вы не можете делать такие вещи, как cal -3. Вы получаете правильные недели, но они не выровнены должным образом. Простое, но не полное решение — проверить, вызывается ли calбез аргументов, например:

function cal {
    if [[ $# -eq 0 ]]; then
        paste -d' ' <((echo ' '{,};ncal -w $@|tail -1)|fold -w3) <(script /dev/null -qc "cal $@")
    else
        /usr/bin/cal "$@"
    fi
}
0
27.01.2020, 19:49

Обновление :текущая версия calподдерживает это напрямую (это на Linux):

bash-5.0$ cal -w
       July 2020       
   Mo Tu We Th Fr Sa Su
27        1  2  3  4  5
28  6  7  8  9 10 11 12
29 13 14 15 16 17 18 19
30 20 21 22 23 24 25 26
31 27 28 29 30 31      
                       
bash-5.0$ cal --version
cal from util-linux 2.35.2
0
26.07.2020, 11:20

Существует три calendarпрограммы. Оригиналcal(из BSD ),ncal(в Linux )и gcal.

Все могут печатать номера недель (с правильными параметрами ).

calиз утилиты -linux 2.36.1 работает с cal -w, ncalработает с ncal -bwи gcalработает сgcal -K:

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

$ ncal -bw
       April 2021          
 w| Su Mo Tu We Th Fr Sa   
13|              1  2  3   
14|  4  5  6  7  8  9 10   
15| 11 12 13 14 15 16 17   
16| 18 19 20 21 22 23 24   
17| 25 26 27 28 29 30 

$ gcal -K
     April 2021
 Su Mo Tu We Th Fr Sa CW
              1  2  3 13
  4  5  6  7  8  9 10 14
 11 12 13 14 15 16 17 15
 18 19 20 21 22 23 24 16
 25 26 27 28 29 30    17
1
23.04.2021, 23:03

Теги

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