elig Asked: 2018-11-10 09:22:57 +0800 CST2018-11-10 09:22:57 +0800 CST 2018-11-10 09:22:57 +0800 CST 如何使用 bash 生成月份列表? 772 如何使用 bash 以编程方式生成一年的完整月份名称? bash date 5 个回答 Voted Best Answer Stephen Kitt 2018-11-10T09:27:30+08:002018-11-10T09:27:30+08:00 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'. RudiC 2018-11-10T10:00:42+08:002018-11-10T10:00:42+08:00 虽然更喜欢该locale提案,但假设 GNU 实现date,这个将date只运行一次而不是 12 次: printf "%02d/01/2000\n" {1..12} | LC_ALL=C date +%B -f- January February March April . . . Jeff Schaller 2018-11-10T10:45:44+08:002018-11-10T10:45:44+08:00 您可能并不打算将其限制为 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 初始分配以秒为单位设置当前时间和当前月份;“本月”变量初始化为当前月份,“秒”变量初始化为当前时间(以秒为单位)。 第一个循环通过将“seconds”变量增加一天的秒数,使我们退出当前月份。一旦我们离开当前月份,打印新月份的名称。 第二个循环贯穿一年,直到我们再次找到当前月份;该循环内部的内部循环增加“秒”,直到该月的最后一天。一旦内部循环完成,我们增加一天,然后打印新月份的名称。然后外部(第二个)循环继续完成。 user543761 2022-10-04T08:54:11+08:002022-10-04T08:54:11+08:00 使用 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 elig 2018-11-10T09:22:57+08:002018-11-10T09:22:57+08:00 使用 bash 的序列表达式和for循环在 12 个月内迭代GNU coreutils date命令: months() { for i in {1..12}; do date +%B -d "$i/01/1980" ; done ; } 将生成monthsshell 函数,该函数将按时间顺序逐行输出 12 个月的完整字母名称。 说明:我们要求date命令输出一个月的完整字母名称(+%B),仅用于我们指定的日期(-d);在我们的例子中,通过 bash 的序列表达式生成的数字表示来迭代 12 个月。 注意:日期字符串中 $i 之后的内容只需要date通过设置它的相对位置来让知道可迭代的函数,因此这个片段中的日期和年份(即 01/1980)是任意选择的。
locale
将告诉您当前语言环境中的月份名称:因此:
如果您希望月份在不同的行中,请将输出通过管道传输到
tr ';' '\n'
.虽然更喜欢该
locale
提案,但假设 GNU 实现date
,这个将date
只运行一次而不是 12 次:您可能并不打算将其限制为 bash,但是……您可以。
仅使用bash,但使用 bash 4.2 或更高版本(以支持
printf %(fmt)T
),并仅假设一天中的秒数(尽管它应该是闰秒安全的):初始分配以秒为单位设置当前时间和当前月份;“本月”变量初始化为当前月份,“秒”变量初始化为当前时间(以秒为单位)。
第一个循环通过将“seconds”变量增加一天的秒数,使我们退出当前月份。一旦我们离开当前月份,打印新月份的名称。
第二个循环贯穿一年,直到我们再次找到当前月份;该循环内部的内部循环增加“秒”,直到该月的最后一天。一旦内部循环完成,我们增加一天,然后打印新月份的名称。然后外部(第二个)循环继续完成。
使用 FreeBSD 实现
date
(也可以在 macos 上找到):使用 bash 的序列表达式和for循环在 12 个月内迭代GNU coreutils
date
命令:将生成
months
shell 函数,该函数将按时间顺序逐行输出 12 个月的完整字母名称。说明:我们要求
date
命令输出一个月的完整字母名称(+%B),仅用于我们指定的日期(-d);在我们的例子中,通过 bash 的序列表达式生成的数字表示来迭代 12 个月。注意:日期字符串中 $i 之后的内容只需要
date
通过设置它的相对位置来让知道可迭代的函数,因此这个片段中的日期和年份(即 01/1980)是任意选择的。