AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 766633
Accepted
Nickotine
Nickotine
Asked: 2024-01-11 15:27:27 +0800 CST2024-01-11 15:27:27 +0800 CST 2024-01-11 15:27:27 +0800 CST

如何从当前日期中减去格式为“xyz/[int][int]/[int][int][int][int]”的日期?

  • 772

设想

我的容器的上次部署日期格式如下:

月/日/年或 2024 年 2 月 11 日。

我无法更改他们输出上次部署日期的方式。

我想从当前日期中减去上次部署日期,然后如果上次部署日期超过 2 个月,则写入文件。

示例container1-last-deploy.txt:

last deployed: jan/01/2024

我有几个这样的文件。

挑战在于月份是用字母给出的。我可以使用正则表达式来获取日期。

我想到的一个解决方案是将月份放在字典中,例如:

dict=(
  ['jan']=1
  ['feb']=2
)

但一定有更好的方法。

是否可以将字母月份转换为整数?

这是针对 macOS 上的 bash,最好是 bash 3 解决方案。

bash
  • 3 3 个回答
  • 73 Views

3 个回答

  • Voted
  1. Best Answer
    aviro
    2024-01-11T17:51:15+08:002024-01-11T17:51:15+08:00

    MacOS date- 将日期字符串转换为自纪元以来的秒数

    date命令可以通过libc函数理解字符串格式的月份strptime(3)。我没有 macos,所以我无法测试我的答案,但根据 macosdate 手册页:

    date [-jRu] -f input_fmt new_date [+output_fmt]
    

    [...]

       -f      Use input_fmt as the format string to parse the new_date provided rather than using the
               default [[[mm]dd]HH]MM[[cc]yy][.ss] format.  Parsing is done using strptime(3).
    

    现在您只需要了解如何从手册页中设置输入日期的格式strptime(3):

           %b or %B or %h
                  The month name according to the current locale,  in  abbreviated
                  form or the full name.
    
           %d or %e
                  The day of month (1-31).
    
           %Y     The year, including century (for example, 1991).
    

    所以根据这个,输入格式应该是:"%b/%e/%Y"。

    接下来,您需要使用以下标志date:

       -j      Do not try to set the date.  This allows you to use the -f flag in addition to the + option
               to convert one date format to another.  Note that any date or time components unspecified
               by the -f format string take their values from the current time.
    

    最后,由于您希望能够从结果中减去当前时间,因此您需要确保您的 + output_fmt为:

           %s     The number of seconds since the Epoch, 1970-01-01 00:00:00
                  +0000 (UTC).  Leap seconds are not counted unless leap
                  second support is available.
    

    因此,将日期格式转换为纪元的结果命令应该是:

    $ DATE="jan/01/2024"
    $ date -jf "%b/%e/%Y" $DATE +%s
    1704060000
    

    再说一次,因为我没有 Macos,所以我无法测试这一点来确认。我也不确定它是否会接受小写的月份,但如果您必须将月份大写,您可以替换$DATE为${DATE^}

    为了完整起见,我还将展示如何使用以下命令执行相同的操作:

    GNU date- 将日期字符串转换为自纪元以来的秒数

    这更容易一些,因为 GNU 版本date给予了更多自由

    从其手册页:

           The --date=STRING is a mostly free format human readable date
           string such as "Sun, 29 Feb 2004 16:21:42 -0800" or "2004-02-29
           16:21:42" or even "next Thursday".  A date string may contain
           items indicating calendar date, time of day, time zone, day of
           week, relative time, relative date, and numbers.  An empty string
           indicates the beginning of the day.  The date string format is
           more complex than is easily documented here but is fully
           described in the info documentation.
    

    因此,从我在机器上的测试来看,您应该从输入中删除斜杠,以便date命令理解它:

    $ DATE="jan/01/2024"
    $ echo ${DATE//\// }
    jan 01 2024
    $ date --date "${DATE//\// }"  +%s
    1704060000
    

    从当前日期中减去

    现在您已获得原始日期的纪元时间。只需将其存储到变量中即可。例如,在 MacOS 中:

    $ ORIG_DATE=$(date -jf "%b/%e/%Y" $DATE +%s)
    

    要查看自纪元以来的当前日期(以秒为单位):

    $ date +%s
    1704965965
    

    所以现在要计算以秒为单位的差异,这很简单:

    $ echo $(( $(date +%s ) - $ORIG_DATE ))
    905967
    
    • 2
  2. Hans-Martin Mosner
    2024-01-11T17:47:38+08:002024-01-11T17:47:38+08:00

    您应该尝试获得确切的要求(也许您有这些要求,但您没有在此处说明)。

    • 一是月份缩写所假定的区域设置。例如,在德语区域设置中,在解析纯英语应用程序打印的日期时,几个月的名称可能会导致问题(例如,德语中的mayismai和octis okt)。

      如果使用的月份名称与当前区域设置匹配,则date -d "$(echo jan/01/2024 | tr / ' ')"可以简单地解析部署日期。

    • 另一个问题是如何计算日期差异:

      • 如果您要计算天数(大约 60 天),您可以使用格式+%s参数将部署日期和当前日期转换为秒,减去这些数字,然后检查结果是否大于 60*86400。

      • 如果您想遵守一些更复杂的规则(例如,比较月份中的某一天),您仍然可以在 bash 中执行此操作,但会变得更加困难。

    • 1
  3. Ed Morton
    2024-01-12T01:23:34+08:002024-01-12T01:23:34+08:00

    使用任何date和任何awk都会执行您所描述的操作:

    $ awk -v now="$(date +%m/%Y)" -v dif=2 -F'[ /]' '
        BEGIN {
            split(now,n)
            now = n[1] + (n[2] * 12)
        }
        {
            mth = ( index("janfebmaraprmayjunjulaugsepoctnovdec",$3) + 2 ) / 3
            cur = mth + ($5 * 12)
        }
        (now - cur) > dif
    ' file
    last deployed: oct/01/2023
    

    上面的代码是在此输入文件上运行的:

    $ cat file
    last deployed: oct/01/2023
    last deployed: nov/01/2023
    last deployed: dec/01/2023
    last deployed: jan/01/2024
    

    如果输入中的月份名称不全是小写,例如Jan或JAN,则只需在脚本中更改$3为。tolower($3)

    • 0

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve