【问题标题】:Calendar calculations in bashbash 中的日历计算
【发布时间】:2010-10-16 21:24:39
【问题描述】:

我想在 bash 中进行一些日历操作 - 具体来说,我想找出给定月份的最后日期(包括闰年,并且为查找准备表格对我来说不是一个有效的解决方案)。

假设我有以下代码:

$year=2009
$start_month=2
$end_month=10
for $month in $(seq $start_month $end_month); do
  echo "Last date of "$(date +"%B" -d "${year}-${month}-01")" is: " ???
done

我不知道如何做这样的事情。我虽然 date -d 会像 POSIX mktime 一样工作,并将无效日期折叠为其有效等价物,所以我可以说类似 date -d "2009-03-00" 并得到“2009-02-28”,但没有这样的运气。

有没有办法只使用标准 GNU 环境中的 bash 提供的功能?

【问题讨论】:

    标签: linux bash shell command-line


    【解决方案1】:

    试试:date -d 'yesterday 2009-03-01'

    直觉我知道。 date 的早期版本用于以 POSIX 方式工作。

    【讨论】:

    • 嘿,太棒了。谢谢。显然我应该阅读信息文档(不是我现在要阅读,我只是受不了信息浏览器)。
    • '2009-02-01 last day month' 也可以,但这样更优雅。
    【解决方案2】:

    date(1) 的 -d 是 GNU 特定的;所以使用它只能在 GNU Linux 上使用。

    一个更便携的解决方案(这甚至应该在sh AFAIK 中工作),是这样的:

    : $(cal 4 2009); echo $_
    

    【讨论】:

    • 绝招!绝对是“开箱即用”。我不会使用它的原因:它会产生一条错误消息 - 我可以重定向它,但它仍然不好。此外 - date -d 可能是 GNU 特定的,但我正在编写一个 GNU bash 脚本 - 期望它被部署在 GNU 环境(也可能是 Solaris)上是有效的
    • 它不会产生错误。你没有把冒号放在前面吗?这不是本例中的提示,您实际上需要输入冒号-空格-美元...等。
    • @Guss:应该没有错误信息。检查您是否正确复制了它,如果是,请显示错误消息或在 freenode 上的#bash 中与我讨论它。此外,即使它是 GNU bash,您也不能期望处于 GNU 环境中。 Bash 在很多非 GNU 环境中都可用(甚至默认情况下)。
    • 我不确定它曾经为我做了什么错误消息,可能是因为我没有正确复制和粘贴,但此时我还想指出,这并没有完全可以在 bash 中工作 - 它确实可以在 sh 中工作,但在正确的完整 bash 模式下,它会输出 _lp_reset_runtime。通过滥用正则表达式匹配,我确实设法以完全 bash 的方式使用 cal,如下所示:[[ "$(cal 2 2016)" =~ .*\ ([0-9]+) ]] && echo ${BASH_REMATCH[1]}
    【解决方案3】:

    如果您不介意使用 grep/awk/perl,可以查看cal

    $ cal 4 2009
         April 2009
    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
    

    编辑(MarkusQ):为了弥补我在下面的笑话解决方案,我将为您的解决方案做出贡献:

    cal 4 2009 | tr ' ' '\n' | grep -v ^$ | tail -n 1
    

    【讨论】:

    • 类似这样的东西:cal 2 2009 | perl -nle 'm/\S/ 和 $line = $_; END { @r = 拆分 /\s/,$line;打印弹出@r; }' 我猜它会起作用,但它不是很好:-/
    • @MarkusQ:你的解析器比我的更干净,但我仍然更喜欢史蒂夫贝克的解决方案。无论如何谢谢:-)
    • cal | awk '!/^$/{E=$NF} END{print E}'
    【解决方案4】:

    嗯,一种方法是循环观察当前日期,直到月份部分发生变化,将日期部分保存一轮。这将为您提供该月的第一天和最后一天,但它可能太慢了。

    2009 年 4 月 1 日发布

    【讨论】:

    • 哈。过去的日期也会有问题,除非我可以使用时间机器。
    猜你喜欢
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多