두 명령이 각각 하나의 원하는 작업을 수행 할 때 두 가지 명령을 모두 수행 할 때이 기능을 좋아하지 않습니까?
이것이하는 일 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
답변
이러한 명령 중 어느 것도 귀하의 요구 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
마지막 열의 주 번호를 오른쪽으로 인쇄합니다.
참고 문헌
답변
오늘 날짜를 강조 표시하고 다음과 $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
답변
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
훨씬 더 지저분하고 다른 하나와 호환되지 않습니다. 핀 …
답변
와 함께 두 출력을 나란히 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)
답변
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.
답변
slm 의 답변 에 대한 충분한 답변이 없으면 gcal 을 사용하여 Mac OS에 설치할 수 있습니다brew install gcal
.
(여기에서 대답을 먼저 찾은 다음 이 질문 에 대한 대답 은 다르지만 유닉스 대답에는 Mac에 설치하는 데 필요한 모든 정보가 부족합니다.)
답변
다음은 코드가 짧고 현재 달 이외의 다른 날짜에 잘 작동하는 솔루션입니다. 미국 사람들에게는 죄송합니다. 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}
'