![如何使用 bash 生成月份列表?](https://linux22.com/image/141886/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20bash%20%E7%94%9F%E6%88%90%E6%9C%88%E4%BB%BD%E5%88%97%E8%A1%A8%EF%BC%9F.png)
如何使用 bash 以编程方式生成一年的完整月份名称?
答案1
locale
会告诉您当前语言环境中的月份名称:
locale mon
因此:
$ LC_TIME=en_GB.UTF-8 locale mon
January;February;March;April;May;June;July;August;September;October;November;December
$ LC_TIME=fr_FR.UTF-8 locale mon
janvier;février;mars;avril;mai;juin;juillet;août;septembre;octobre;novembre;décembre
如果您希望月份位于单独的行上,请将输出通过管道传输到tr ';' '\n'
.
答案2
您可能无意将其限制为 bash,但是......您可以。
使用仅有的bash,但 bash 4.2 或更高版本(以支持printf %(fmt)T
),并且仅假设一天中的秒数(尽管它应该是闰秒安全的):
#!/bin/bash
now=$(printf '%(%s)T' -1)
thism=$(printf '%(%B)T' "$now")
nextm=$thism
s=$now
until [[ "$thism" != "$nextm" ]]
do
s=$((s+86400))
nextm=$(printf '%(%B)T' "$s")
done
printf '%(%B)T\n' "$s"
while [[ "$thism" != "$(printf '%(%B)T' "$s")" ]]
do
while [[ "$(printf '%(%B)T' "$s")" == "$(printf '%(%B)T' $((s + 86400)))" ]]
do
s=$((s+86400))
done
s=$((s+86400))
printf '%(%B)T\n' "$s"
done
初始分配设置当前时间(以秒为单位)和当前月份; “本月”变量被初始化为当前月份,“秒”变量被初始化为当前时间(以秒为单位)。
第一个循环通过将“秒”变量增加一天的秒数来让我们脱离当前月份。当当前月份结束后,打印新月份的名称。
第二个循环遍历一年,直到我们再次找到当前月份;该循环内部的内部循环会增加“秒”,直到该月的最后一天。内部循环完成后,我们增加一天,然后打印新月份的名称。然后,外部(第二个)循环继续完成。
答案3
虽然更喜欢这个locale
提案,但假设 GNU 实现了date
,这个提案只会运行date
一次,而不是 12 次:
printf "%02d/01/2000\n" {1..12} | LC_ALL=C date +%B -f-
January
February
March
April
.
.
.
答案4
使用 FreeBSD 实现date
(在 Macos 上也可以找到):
for i in 1 2 3 4 5 6 7 8 9 10 11 12
do
date -v"$i"m +%B
done