我有带日期的文件:
Mar 16
Mar 12
Mar 13
Mar 19
Mar 14
Mar 17
Run Code Online (Sandbox Code Playgroud)
我需要计算到现在为止已经过去的天数。我来了这个功能:
datediff() {
d1=$(date -d "$1" +%s);
d2=$(date -d "$2" +%s);
echo $(( (d1 - d2) / 86400 )) days;
}
$ datediff 'now' '13 Mar'
114 days
Run Code Online (Sandbox Code Playgroud)
但我需要一些循环来计算每一行
这里不需要 shell 循环。你可以这样做:
date -f file +%s |
awk 'BEGIN{srand(); now = srand()}
{print int((now - $0) / 86400), "days"}'
Run Code Online (Sandbox Code Playgroud)
请注意,-d和-f是 GNU 实现的扩展date。要注意的是Dec 31会被解释成Dec 31的这一年,所以在未来。
如果您想使用 shell 循环,您可能更喜欢具有内置日期操作支持的 shell,例如zsh或ksh93。
要将这些时间戳解释为过去的时间(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
Run Code Online (Sandbox Code Playgroud)
除了英文缩写之外,那个还有一个好处是可以理解用户的月份名称缩写。
您可以使用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
Run Code Online (Sandbox Code Playgroud)
这里的脚本采用一个参数:输入文件。虽然它可以从文件中读取一行,但它会调用您的datediff函数传递now以及line它从文件中读取的内容。