UNIX에서 달력 강조 표시

UNIX에서 달력 강조 표시

여러 번 시도했지만 연감에서 여러 날짜를 강조표시할 수 없습니다.

cal -y
2022                               

       January               February                 March       
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                   1          1  2  3  4  5          1  2  3  4  5   
 2  3  4  5  6  7  8    6  7  8  9 10 11 12    6  7  8  9 10 11 12   
 9 10 11 12 13 14 15   13 14 15 16 17 18 19   13 14 15 16 17 18 19   
16 17 18 19 20 21 22   20 21 22 23 24 25 26   20 21 22 23 24 25 26   
23 24 25 26 27 28 29   27 28                  27 28 29 30 31         
30 31                                                                
        April                   May                   June        
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                1  2    1  2  3  4  5  6  7             1  2  3  4   
 3  4  5  6  7  8  9    8  9 10 11 12 13 14    5  6  7  8  9 10 11   
10 11 12 13 14 15 16   15 16 17 18 19 20 21   12 13 14 15 16 17 18   
17 18 19 20 21 22 23   22 23 24 25 26 27 28   19 20 21 22 23 24 25   
24 25 26 27 28 29 30   29 30 31               26 27 28 29 30         
                                                                     
        July                  August                September     
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                1  2       1  2  3  4  5  6                1  2  3   
 3  4  5  6  7  8  9    7  8  9 10 11 12 13    4  5  6  7  8  9 10   
10 11 12 13 14 15 16   14 15 16 17 18 19 20   11 12 13 14 15 16 17   
17 18 19 20 21 22 23   21 22 23 24 25 26 27   18 19 20 21 22 23 24   
24 25 26 27 28 29 30   28 29 30 31            25 26 27 28 29 30      
31                                                                   
       October               November               December      
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                   1          1  2  3  4  5                1  2  3   
 2  3  4  5  6  7  8    6  7  8  9 10 11 12    4  5  6  7  8  9 10   
 9 10 11 12 13 14 15   13 14 15 16 17 18 19   11 12 13 14 15 16 17   
16 17 18 19 20 21 22   20 21 22 23 24 25 26   18 19 20 21 22 23 24   
23 24 25 26 27 28 29   27 28 29 30            25 26 27 28 29 30 31   
30 31                                                                

나는 연감에서 여러 날짜를 강조하고 싶습니다. UNIX에서는 가능합니까?

답변1

cal예를 들어 awk를 사용하여 출력을 조정하는 스크립트를 작성할 수 있습니다 .

$ cat tgtDates
January 25
June 13

$ cat tst.sh
#!/usr/bin/env bash

cal 2022 |
awk '
    BEGIN {
        highlightOn  = "["
        highlightOff = "]"
    }
    NR==FNR {
        tgtDates[$0]
        next
    }
    NF == 3  { split($0,months); print; next } # month list
    !/[0-9]/ { print; next }            # blank line or days list
    {                                   # dates list
        for ( mthNr=1; mthNr<=3; mthNr++ ) {
            mthName   = months[mthNr]
            inDayNrs  = substr($0,1,20)
            outDayNrs = ""
            while ( match(inDayNrs,/[0-9]+/) ) {
                inDayNr   = substr(inDayNrs,RSTART,RLENGTH)
                curDate   = mthName " " inDayNr
                outDayNr  = (curDate in tgtDates ? highlightOn inDayNr highlightOff : inDayNr )
                outDayNrs = outDayNrs substr(inDayNrs,1,RSTART-1) outDayNr
                inDayNrs  = substr(inDayNrs,RSTART+RLENGTH)
            }
            printf "%s   ", outDayNrs inDayNrs
            $0 = substr($0,24)
        }
        print ""
    }
' "$1" -

$ ./tst.sh tgtDates
                               2022
       January               February                 March
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                   1          1  2  3  4  5          1  2  3  4  5
 2  3  4  5  6  7  8    6  7  8  9 10 11 12    6  7  8  9 10 11 12
 9 10 11 12 13 14 15   13 14 15 16 17 18 19   13 14 15 16 17 18 19
16 17 18 19 20 21 22   20 21 22 23 24 25 26   20 21 22 23 24 25 26
23 24 [25] 26 27 28 29   27 28                  27 28 29 30 31
30 31
        April                   May                   June
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                1  2    1  2  3  4  5  6  7             1  2  3  4
 3  4  5  6  7  8  9    8  9 10 11 12 13 14    5  6  7  8  9 10 11
10 11 12 13 14 15 16   15 16 17 18 19 20 21   12 [13] 14 15 16 17 18
17 18 19 20 21 22 23   22 23 24 25 26 27 28   19 20 21 22 23 24 25
24 25 26 27 28 29 30   29 30 31               26 27 28 29 30

        July                  August                September
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                1  2       1  2  3  4  5  6                1  2  3
 3  4  5  6  7  8  9    7  8  9 10 11 12 13    4  5  6  7  8  9 10
10 11 12 13 14 15 16   14 15 16 17 18 19 20   11 12 13 14 15 16 17
17 18 19 20 21 22 23   21 22 23 24 25 26 27   18 19 20 21 22 23 24
24 25 26 27 28 29 30   28 29 30 31            25 26 27 28 29 30
31
       October               November               December
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                   1          1  2  3  4  5                1  2  3
 2  3  4  5  6  7  8    6  7  8  9 10 11 12    4  5  6  7  8  9 10
 9 10 11 12 13 14 15   13 14 15 16 17 18 19   11 12 13 14 15 16 17
16 17 18 19 20 21 22   20 21 22 23 24 25 26   18 19 20 21 22 23 24
23 24 25 26 27 28 29   27 28 29 30            25 26 27 28 29 30 31
30 31

분명히 위의 대상 날짜를 래핑하여 [...]명령이 작동 중임을 보여주기 위해 표시했습니다. 이로 인해 행 레이아웃이 이동되고 날짜가 변경되는 대신 색상이 지정되었습니다.

        highlightOn  = "["
        highlightOff = "]"

콘텐츠를 강조하기 위해 배경 및/또는 전경 색상을 변경하고, 원하는 이벤트 유형에 따라 배경/전경 색상을 다르게 설정할 수도 있습니다. 예를 들면 다음과 같습니다.

$ cat tgtDates
January 25 Birthday
June 13 Meeting
September 2
December 25 Holiday

$ cat tst.sh
#!/usr/bin/env bash

cal 2022 |
awk -v today="$(date +'%B %-d')" '
    BEGIN {
        split("BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE",tputColors)
        for (i in tputColors) {
            colorName = tputColors[i]
            colorNr = i-1

            cmd = "tput setaf " colorNr
            fgEscSeq[colorName] = ( (cmd | getline escSeq) > 0 ? escSeq : "<" colorName ">" )
            close(cmd)

            cmd = "tput setab " colorNr
            bgEscSeq[colorName] = ( (cmd | getline escSeq) > 0 ? escSeq : "<" colorName ">" )
            close(cmd)
        }

        cmd = "tput sgr0"
        colorOff = ( (cmd | getline escSeq) > 0 ? escSeq : "<sgr0>" )
        close(cmd)

        highlight["Today"]    = bgEscSeq["BLACK"]  fgEscSeq["WHITE"]
        highlight["Holiday"]  = bgEscSeq["RED"]    fgEscSeq["YELLOW"]
        highlight["Birthday"] = bgEscSeq["CYAN"]   fgEscSeq["RED"]
        highlight["Meeting"]  = bgEscSeq["YELLOW"] fgEscSeq["GREEN"]
        highlight[""]         = bgEscSeq["GREEN"]  fgEscSeq["WHITE"]

        tgtDates[today] = "Today"
    }
    NR==FNR {
        tgtDates[$1" "$2] = $3
        next
    }
    NF == 3  { split($0,months); print; next } # month list
    !/[0-9]/ { print; next }            # blank line or days list
    {                                   # dates list
        for ( mthNr=1; mthNr<=3; mthNr++ ) {
            mthName   = months[mthNr]
            inDayNrs  = substr($0,1,20)
            outDayNrs = ""
            while ( match(inDayNrs,/[0-9]+/) ) {
                inDayNr   = substr(inDayNrs,RSTART,RLENGTH)
                curDate   = mthName " " inDayNr
                highlightOn = highlightOff = ""
                if ( curDate in tgtDates ) {
                    dateType = tgtDates[curDate]
                    highlightOn = ( dateType in highlight ? highlight[dateType] : highlight[""] )
                    highlightOff = colorOff
                }
                outDayNr  = highlightOn inDayNr highlightOff
                outDayNrs = outDayNrs substr(inDayNrs,1,RSTART-1) outDayNr
                inDayNrs  = substr(inDayNrs,RSTART+RLENGTH)
            }
            printf "%s   ", outDayNrs inDayNrs
            $0 = substr($0,24)
        }
        print ""
    }
' "$1" -

여기에 이미지 설명을 입력하세요.

답변2

이 awk 스크립트에 감사드립니다. 이것은 훌륭하지만 우분투에서 작동하려면 약간의 조정이 필요했습니다. Ubuntu 20.04.4 LTS 및 18.04.6 LTS에서 성공적으로 테스트했습니다.

변경 사항은 다음과 같습니다. (이전 형식과 새 형식의 차이점)

2c2
< cal 2022 |
---
> ncal -bh 2022 |
55,56c55,56
<             printf "%s   ", outDayNrs inDayNrs
<             $0 = substr($0,24)
---
>             printf "%s  ", outDayNrs inDayNrs
>             $0 = substr($0,23)

단순화를 위해 개정 내용은 다음과 같습니다.

#!/usr/bin/env bash
ncal -bh 2022 |
awk -v today="$(date +'%B %-d')" '
    BEGIN {
        split("BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE",tputColors)
        for (i in tputColors) {
            colorName = tputColors[i]
            colorNr = i-1

            cmd = "tput setaf " colorNr
            fgEscSeq[colorName] = ( (cmd | getline escSeq) > 0 ? escSeq : "<" colorName ">" )
            close(cmd)

            cmd = "tput setab " colorNr
            bgEscSeq[colorName] = ( (cmd | getline escSeq) > 0 ? escSeq : "<" colorName ">" )
            close(cmd)
        }

        cmd = "tput sgr0"
        colorOff = ( (cmd | getline escSeq) > 0 ? escSeq : "<sgr0>" )
        close(cmd)

        highlight["Today"]    = bgEscSeq["BLACK"]  fgEscSeq["WHITE"]
        highlight["Holiday"]  = bgEscSeq["RED"]    fgEscSeq["YELLOW"]
        highlight["Birthday"] = bgEscSeq["CYAN"]   fgEscSeq["RED"]
        highlight["Meeting"]  = bgEscSeq["YELLOW"] fgEscSeq["GREEN"]
        highlight[""]         = bgEscSeq["GREEN"]  fgEscSeq["WHITE"]

        tgtDates[today] = "Today"
    }
    NR==FNR {
        tgtDates[$1" "$2] = $3
        next
    }
    NF == 3  { split($0,months); print; next } # month list
    !/[0-9]/ { print; next }            # blank line or days list
    {                                   # dates list
        for ( mthNr=1; mthNr<=3; mthNr++ ) {
            mthName   = months[mthNr]
            inDayNrs  = substr($0,1,20)
            outDayNrs = ""
            while ( match(inDayNrs,/[0-9]+/) ) {
                inDayNr   = substr(inDayNrs,RSTART,RLENGTH)
                curDate   = mthName " " inDayNr
                highlightOn = highlightOff = ""
                if ( curDate in tgtDates ) {
                    dateType = tgtDates[curDate]
                    highlightOn = ( dateType in highlight ? highlight[dateType] : highlight[""] )
                    highlightOff = colorOff
                }
                outDayNr  = highlightOn inDayNr highlightOff
                outDayNrs = outDayNrs substr(inDayNrs,1,RSTART-1) outDayNr
                inDayNrs  = substr(inDayNrs,RSTART+RLENGTH)
            }
            printf "%s  ", outDayNrs inDayNrs
            $0 = substr($0,23)
        }
        print ""
    }
' "$1" -

관련 정보