![UNIX 中的日历突出显示](https://linux22.com/image/202717/UNIX%20%E4%B8%AD%E7%9A%84%E6%97%A5%E5%8E%86%E7%AA%81%E5%87%BA%E6%98%BE%E7%A4%BA.png)
我尝试过几次,但无法突出显示年历中的多个日期
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 中运行。我已经在 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" -