我有 2 个日期,start=20190903
并且end=20210912
想要增加直到开始接近结束,增量是 13 天。
有以下代码,但它超出了结束。
#! /usr/bin/env bash
start="20190903"
end="20210912"
startdate="$(date -d ${start} +'%Y-%m-%d')"
enddate="$(date -d ${end} +'%Y-%m-%d')"
echo ${startdate}
echo ${enddate}
while [ "${startdate}" < "${enddate}" ]; do
echo ${startdate}
startdate="$( date -d "${startdate} + 13 days" +'%Y-%m-%d')"
done
答案1
通过将 thestartdate+interval
与 end 进行比较,您可以防止超越它。
#!/bin/bash
start="20190903"
end="20210912"
interval=1123200
# 13 days = 13 * 24 * 60 *60
startdate=$( date --utc -d ${start} +%s )
enddate=$( date --utc -d ${end} +%s )
echo "$( date --utc -d @${startdate} +"%Y-%m-%d" ) (start)"
next=${startdate}
while [[ "$(( next+interval ))" -lt "${enddate}" ]] ; do
next=$(( next+interval ))
nextdate=$( date --utc -d @${next} +"%Y-%m-%d" )
echo "${nextdate}"
done
echo "$( date --utc -d @${enddate} +"%Y-%m-%d" ) (end)"
我不确定你添加13天的方式,所以我把它改为从1970-01-01开始的秒。至少现在你知道另一种方法了。
答案2
扩展比利叔叔的评论[
是一个常规命令,因此您使用的<
是标准输入重定向。如果您没有收到bash: line 9: 2021-09-12: No such file or directory
错误,则可能是您之前使用>
.如果是这样的话,那么
[ "${startdate}" < "${enddate}" ]
评估结果与
[ "${startdate}" ]
只要$startdate
不未设置或为空,即为真。所以,你有一个无限循环。
更改为使用[[
如
while [[ "${startdate}" < "${enddate}" ]]; do
修复了这个问题,因为这是一种具有自己语法的特殊形式,而不是常规命令,并且<
/>
不会被解析为重定向。
编辑:[[
是一种打击主义。如果您希望它能够与[
POSIX 兼容,您可以使用-lt
.但是,由于它进行数字比较而不是像字典那样<
进行比较,因此您必须-
从日期格式中删除 s:
#!/bin/sh
startdate="20190903"
enddate="20210912"
echo ${startdate}
echo ${enddate}
while [ "${startdate}" -lt "${enddate}" ]; do
echo ${startdate}
startdate="$( date -d "${startdate} + 13 days" +'%Y%m%d')"
done
就您而言,通过这样的更改,您最终会得到更少的代码,因为您不再需要与/start
相同。startdate
end
enddate
编辑2:另一种选择似乎是转义<
,[ "${startdate}" \< "${enddate}" ]
但这似乎只适用于bash。它不是 POSIX,并且至少在 zsh 上失败。