【问题标题】:Loop over a range of dates. d=$(date -I -d "$d + 1 day") not working [duplicate]循环一系列日期。 d=$(date -I -d "$d + 1 day") 不工作[重复]
【发布时间】:2020-04-15 19:01:09
【问题描述】:

我正在尝试遍历一个日期范围,并将答案复制到 this 帖子上。

我的脚本'loop_run_local.sh':

d=2019-11-12
while [ "$d" != 2019-11-14 ]; do
  echo 'Starting Data Extract...'
  echo 'run date is: ' $d
  echo 'Starting Transactions Extract...'
  python3.7 flagship_ecom/run_transactions.py $d    
  d=$(date -I -d "$d + 1 day")
done

这似乎只适用于第一次迭代,不适用于后续日期,所以我猜有些东西不适用于d=$(date -I -d "$d + 1 day")

在我按 ctrl+z 停止循环之前的终端输出:

bash-3.2$ ./flagship_ecom/loop_run_local.sh
Starting Data Extract...
run date is:  2019-11-12
Starting Transactions Extract...
pageToken is:0 : 2019-11-12
/Users/macuser/Library/Python/3.7/lib/python/site-packages/tqdm/std.py:658: FutureWarning: The Panel class is removed from pandas. Accessing it from the top-level namespace will also be removed in the next version
  from pandas import Panel
Pandas Apply: 100%|██████████████████████████████████████████████████████████████████████████████| 2737/2737 [00:00<00:00, 3156.76it/s]
date: illegal option -- I
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
Starting Data Extract...
run date is:
Starting Transactions Extract...
Traceback (most recent call last):
  File "flagship_ecom/run_transactions.py", line 17, in <module>
    start_date = sys.argv[1]
IndexError: list index out of range
date: illegal option -- I
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
Starting Data Extract...
run date is:
Starting Transactions Extract...
Traceback (most recent call last):
  File "flagship_ecom/run_transactions.py", line 17, in <module>
    start_date = sys.argv[1]
IndexError: list index out of range
date: illegal option -- I
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
Starting Data Extract...
run date is:
Starting Transactions Extract...
^Z
[2]+  Stopped                 ./flagship_ecom/loop_run_local.sh

输出中的这一行:

运行日期为:2019-11-12

对应于 .sh 脚本中的这一行:

echo 'run date is: ' $d

由于开始日期之后的日期为空白,我认为我的日期递增存在问题?

这是以 bash -x per cmets 为前缀时的输出:

bash-3.2$ bash -x ./flagship_ecom/loop_run_local.sh
+ d=2019-11-12
+ '[' 2019-11-12 '!=' 2019-11-14 ']'
+ echo 'Starting Data Extract...'
Starting Data Extract...
+ echo 'run date is: ' 2019-11-12
run date is:  2019-11-12
+ echo 'Starting Transactions Extract...'
Starting Transactions Extract...
+ python3.7 flagship_ecom/run_transactions.py 2019-11-12
pageToken is:0 : 2019-11-12
/Users/macuser/Library/Python/3.7/lib/python/site-packages/tqdm/std.py:658: FutureWarning: The Panel class is removed from pandas. Accessing it from the top-level namespace will also be removed in the next version
  from pandas import Panel
Pandas Apply: 100%|██████████████████████████████████████████████████████████████████████████████| 2737/2737 [00:00<00:00, 2971.93it/s]
++ date -I -d '2019-11-12 + 1 day'
date: illegal option -- I
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
+ d=
+ '[' '' '!=' 2019-11-14 ']'
+ echo 'Starting Data Extract...'
Starting Data Extract...
+ echo 'run date is: '
run date is:
+ echo 'Starting Transactions Extract...'
Starting Transactions Extract...
+ python3.7 flagship_ecom/run_transactions.py
Traceback (most recent call last):
  File "flagship_ecom/run_transactions.py", line 17, in <module>
    start_date = sys.argv[1]
IndexError: list index out of range
^Z
[8]+  Stopped                 bash -x ./flagship_ecom/loop_run_local.sh
bash-3.2$

我使用的是 Mac。

【问题讨论】:

  • 运行 bash -x yourscript 以记录它运行的每个命令,因此我们不需要猜测值是什么。
  • 另外,date 不是 bash 的一部分——它由您的操作系统供应商提供,因此我们需要知道您运行的是什么操作系统。
  • $d 在第一次迭代后为空白,因为date 命令出错,产生空白输出; illegal option -- I 告诉我你没有在你引用的答案中使用相同版本的date,它看起来依赖于 GNU date
  • 嗨,添加了上面使用 -x 调用的输出。另外,我在 Mac 上
  • 如果您已经在使用 Python,您可以将外部循环移到您的 Python 代码中,这通常比 shell 脚本更好地处理日期。

标签: bash


【解决方案1】:

我也碰巧在使用 Mac。这是一个替代脚本,它增加秒数,并发出正常的日历表示:

#!/bin/bash

dsecs=`date '+%s'`
ddate=`date -r $dsecs '+%F'`
while [ "$ddate" != 2019-12-31 ]; do
  echo 'run date is: ' $ddate
  dsecs=$((dsecs + 86400))
  ddate=`date -r $dsecs '+%F'`
done

输出:

run date is:  2019-12-24
run date is:  2019-12-25
run date is:  2019-12-26
run date is:  2019-12-27
run date is:  2019-12-28
run date is:  2019-12-29
run date is:  2019-12-30

您可以使用$ddate 作为要从此脚本调用的程序的输入。

上面的脚本在今天开始迭代;如果您需要在其他日期开始迭代,只需将第一行 dsecs= 替换为 Unix Epoch 值,例如您希望迭代开始日期的中午


关于闰秒

欢迎提供建设性反馈,但 cmets 对此答案提出的担忧以及由于忽略闰秒问题而导致该脚本“错误”的问题是错误的。原因如下:

  1. date 不考虑闰秒,因为 Unix 时间不考虑闰秒 [1];将 86,400 秒添加到 Unix 纪元时间将始终导致 date 产生相同的时间,提前一天 - 即正好一天后
  2. POSIX 时间也不关心闰秒;参见the discussion on this SO question, and its references
  3. 即使闰秒在这里发挥作用,使用 86,400 秒将时钟提前一整天也只会在您从要添加闰秒的日期的午夜开始时失败;否则,86,400 秒后就是“第二天”
  4. 是的,由于闰秒,重复添加 86,400 秒确实会产生偏差(但同样,date 不是)——但到目前为止只有 27 个闰秒,平均间隔 20 个月 [2 ];因此:

    4.1。通常需要几年的时间才能受到这种影响

    4.2。午夜后半分钟或更长时间的开始时间完全消除了这种漂移的影响

    4.3。自 2016 年 12 月 31 日以来没有任何闰秒,因此从那时到现在的日期不必担心

  5. 未来日期(还)根本没有闰秒 - 它们不像闰年那样可预测 - 因此计算未来日期就更不用担心了

因此,date 的操作本身使得重复添加 86,400 秒有效,即使不是这种情况,闰秒重要的情况也很有限。正如我在我的一个 cmets 中所指出的,所有现实世界的工程都是在手头的应用程序的上下文中完成的。在广泛的情况下,闰秒不足以产生足够的影响——或者根本不存在——不考虑它们的解决方案不是错误的......而且也没有结束- 设计。

[1]https://en.wikipedia.org/wiki/Unix_time

[2]https://en.wikipedia.org/wiki/Leap_second

【讨论】:

  • 请注意,使用反引号进行命令替换是不受欢迎的 -- $(...) 自 1991 年首次发布以来一直是 POSIX sh 标准的一部分,并且表现得更好(嵌套正确,不' t 要求反斜杠有额外的转义)。
  • (另外,请参阅How to Answer 的“回答好问题”部分,特别包括关于“之前已经被多次询问和回答”的问题的要点)。
  • 这会忽略闰秒,因此有时会返回错误的结果。
  • @CharlesDuffy:感谢您的集体反馈;至于闰秒,所有现实世界的工程都涉及到一定程度的“容差”;到目前为止,闰秒平均每 20 个月插入一次,因此以中午为起点,脚本方法需要 72,000 年才能产生错误的日​​期;每个考虑这个脚本的人都应该自己决定他们的情况是否只能在接下来的 72,000 年中容忍一个准确的结果
  • 嗯?你不需要累积一天的闰秒来让这段代码行为不端;当您需要添加86401 秒以到达下一个日期并且只添加86400 时,您只需要一天 天,并且代码永远不会超过该日期。 (OTOH,您可以轻松地将硬编码的86400 更改为86401,我没有更多反对的余地)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-25
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 2015-10-16
  • 1970-01-01
  • 2016-03-09
相关资源
最近更新 更多