ncal 또는 cal을 사용하여 특정 형식으로 주 번호 표시


16

두 명령이 각각 하나의 원하는 작업을 수행 할 때 두 가지 명령을 모두 수행 할 때이 기능을 좋아하지 않습니까?

이것이하는 일 cal입니다. 좋은 형식입니다. 주 번호 부족 :

$ cal
    January 2012      
Su Mo Tu We Th Fr Sa  
 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  
29 30 31              

이것이하는 일 ncal입니다. 이상한 형식이지만 주 번호는 다음과 같습니다.

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

내가 원하는 출력의 종류, 실제로 cal와 사이 에 제거 된 ncal -w:

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

답변:


13

이러한 명령 중 어느 것도 귀하의 요구 gcal에 맞지 않으면 대신 원하는 것을 수행하는 데 사용할 수 있습니다 .

$ gcal -K

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

마지막 열의 주 번호를 오른쪽으로 인쇄합니다.

참고 문헌


gcal --starting-day=Monday --with-week-number내 요구에 더 적합하지만이 도구는 훌륭합니다.
k0pernikus

9

오늘 날짜를 강조 표시하고 다음과 $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                

나는 심지어 이소 문제조차 눈치 채지 못했습니다. 그것은 할 것이다 :)
k0pernikus

1
@ k0pernikus : 난 그냥 스크립트 .. (위의 코멘트를 게시 약 35 분) .. 그것은에 휘말리고 된 수정 한 0809해석되고 진수 대신 소수를 이 ... 잘 이제 수 ...합니다
Peter.O

7

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.


편집 : 그러나 이것은 잘못입니다! 방금 1 월 첫 주에 52 번 또는 53 번이있을 수 있음을 알게되었습니다! 따라서 1 월을 예외로 지정하거나에서 모든 주 번호를 추출 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

훨씬 더 지저분하고 다른 하나와 호환되지 않습니다. 핀 ...


별로 좋지 않습니다 :-/. 내 편집을 참조하십시오.
angus 2012 년

7

와 함께 두 출력을 나란히 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)

우아하고 많은 ESR의 17 가지 유닉스 규칙을 구현 합니다. 출력 결과 calncal(다른 접근 방식은 cal또는의 동작을 복제 함)을 실제로 결합하므로 허용되는 답변이어야합니다 ncal.
감독

4

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.

이후 몇 개월 동안 어떻게 작동합니까? 2 월주는 다시 1에서 시작하지 않고, 5/6에서 시작하여 3 월은 9/10에서 시작합니다.
Nikhil Mulley

cal 2012 년 2 월, 이것이 실패했을까요?
Nikhil Mulley 2012 년

@ Nikhil : 나는 당신이 무슨 뜻인지 이해하지 못합니다. 좀 더 깊이 설명해 줄 수 있습니까? 스크립트가 실패합니까 cal 02 2012? 내 테스트에서 작동하는 것 같습니다.
Birei

@ Nikhil : 아, 알았어요. 나는 그 질문을 잘못 이해했다. 그것은 절대 주 번호를 의미하며 매월을 기준으로하지 않습니다. 잠시 동안 잘못된 답변을 삭제하겠습니다.
Birei

1
cool .. 답변을 삭제하지 말고 참조를 위해 보관하십시오.
Nikhil Mulley


0

다음은 코드가 짧고 현재 달 이외의 다른 날짜에 잘 작동하는 솔루션입니다. 미국 사람들에게는 죄송합니다. ISO 형식을 사용합니다. 예를 들어 요일은 월요일입니다. 이것은 cal에 대한 -m 옵션과 날짜에 대한 % 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

이 스크립트를 사용하여 팀을위한 의무 달력을 생성했습니다. 주 번호로 달력을 생성하고 이름을 할당합니다 (단순 라운드 로빈). 출력이 인쇄되면 엑셀로 복사하고 "text to column"을 수행하면됩니다. "fixed"옵션을 사용하여 첫 번째 열에서 "text to column"을 다시 수행하십시오. 이 달력의 장점 (가로 방향과 비교)은 자동 필터 (Alt + dff)를 사용하고 몇 주만 찾을 수 있다는 것입니다.

#! / usr / bin / ksh
y = 2017
세트-팀 1 Petars Justas Richard Jukka Jesper
세트-팀 2 Modestas Timo Mats Andreas

i1 = 0
i2 = 0
wn = 1
자신의 = 1

에코 "WN Month Mo Tu We Th Fr Sa Su; Team1; Team2"
ycal =`m의 경우 12 34 5678 9 10 11 12
하다
IFS =
        cal -m $ m $ y | egrep -v "Mo | ^ $"| 줄을 읽는 동안
        하다
                echo $ line | grep -q $ y && mname = $ line || print $ mname $ line | sed 's /'$ y '//'
        끝난
완료
IFS =
echo "$ ycal"| line2를 읽는 동안
하다
IFS =
        echo "$ line2"| grep -v "12 34 5 6 7"| egrep -q "* 1 | * 1 $"|| 하자 ++
        [$ own -ne $ wn] && {\
                [$ i1 -eq $ {# team1 [@]}-1] && i1 = 0 || i1 ++를 보자; \
                [$ i2 -eq $ {# team2 [@]}-1] && i2 = 0 || i2 ++하자; }
        printf '% 2s % s; % s; % s \ n'$ wn $ line2 $ {team1 [$ i1]} $ {team2 [$ i2]}
        own = $ wn
끝난

죄송합니다. 코드가 조금 불쾌합니다 ... 댓글이 없습니다 ...하지만 잘 작동합니다.)


0

실제로 설치하고 싶지 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
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.