我需要使用 bash 计算日期差异

我需要使用 bash 计算日期差异

我有带有日期的文件:

Mar 16
Mar 12
Mar 13
Mar 19
Mar 14
Mar 17

我需要计算到目前为止已经过去的天数。我有这个功能:

datediff() {     
    d1=$(date -d "$1" +%s);     
    d2=$(date -d "$2" +%s);     
    echo $(( (d1 - d2) / 86400 )) days; 
}
$ datediff 'now' '13 Mar'
114 days

但我需要一些循环来计算每一行

答案1

这里不需要 shell 循环。你可以这样做:

date -f file +%s |
  awk 'BEGIN{srand(); now = srand()}
       {print int((now - $0) / 86400), "days"}'

请注意,-d-f是 GNU 实现的扩展date。请注意,这Dec 31将被解释Dec 31今年,所以在未来。

如果您想使用 shell 循环,您可能更喜欢内置支持日期操作的 shell,例如zshksh93

要将这些时间戳解释为过去的时间(Oct 10例如最近的 10 月 10 日 00:00:00),请使用zsh

#! /bin/zsh -
zmodload zsh/datetime || exit

now=$EPOCHSECONDS
strftime -s year %Y "$now"
(( lastyear = year - 1 ))
while IFS= read -r day; do
  strftime -rs t '%Y %b %d' "$year $day" || continue
  (( t <= now )) || strftime -rs t '%Y %b %d' "$lastyear $day"
  print $(( (now - t) / 86400 ))
done < file

除了英文缩写之外,该功能还有一个好处是可以理解用户的月份名称缩写。

答案2

您可以使用while循环,其中条件基于从标准输入读取的能力:

$ cat input.txt
Mar 16
Mar 12
Mar 13
Mar 19
Mar 14
Mar 17
$ cat ex.sh
#!/bin/bash

datediff() {
    local d1="$(date -d "$1" +%s)"
    local d2="$(date -d "$2" +%s)"

    echo "$(( (d1 - d2) / 86400 )) days"
}

while read line; do
    datediff 'now' "${line}"
done < "${1}"
$ ./ex.sh input.txt
111 days
115 days
114 days
108 days
113 days
110 days

这里的脚本采用一个参数:输入文件。虽然它可以从文件中读取一行,但它会datediff调用您的函数并传递它从文件中读取now的内容。line

答案3

添加可靠的日历支持是一个难题,我建议使用专用程序。幸运的是,有人为我们做了艰苦的工作。

http://www.unixwiz.net/tools/datemath.html:

很多时候,我们需要对日期进行一些数学运算——例如,“今天 + 7 天”——但在传统的 MM/DD/YYYY 格式中,这确实很棘手(尤其是在 shell 脚本中)。为此,我们构建了 datemath 工具,它可以从命令行或 shell 脚本执行这些功能。例子:

$ datemath today + 5
06/23/2003

$ datemath '12/25/2003 - today'
188

$ datemath today + 5 weeks
07/25/2003

when will my machine be up for one year?
$ uptime
 11:09am  up 317 days, 15:38,  7 users,  load average: 0.16, 0.04, 0.01
$ datemath today + 365 - 317
10/24/2003

您可以从网站下载源代码并构建它。

相关内容