【问题标题】:Shell Script to Parse Date用于解析日期的 Shell 脚本
【发布时间】:2016-09-26 00:48:14
【问题描述】:

我正在使用一个 shell 脚本来处理一个包含以下格式数据的 csv 文件:

yyyy-mm-dd,值

每一行都有不同的日期和不同的值。

我想将每一行解析为以下新格式:

yyyy, weeknum, yyyy-mm-dd, 值

其中 yyyy 是从该行日期算起的 4 位数年份,weeknum 是该日、月和年的周数。

我已经使用 date 命令来获取 weeknum,我将日期硬编码为 2016-02-01 作为示例:

echo $(date -j -f '%Y-%m-%d' '2016-02-01' '+%V')

但我只是不确定如何将此日期命令合并到 sed 之类的东西中,在那里我可以根据文件中该行的实际日期值动态和全局地将 yyyy 和 weeknum 值插入每一行。

任何关于如何进行的建议将不胜感激!

莎朗

【问题讨论】:

  • 您能否提供一些示例输入以及您想要的预期输出,以便我们进行测试并确信它们是您正在寻找的结果?跨度>

标签: bash shell date sed osx-yosemite


【解决方案1】:

这可能会:

$ uname -sr
Darwin 15.4.0
$ cat inp
2016-01-01, 5
2016-01-09, 15
2016-02-01, 3.14
$ while IFS=", " read d v; do date -j -f '%Y-%m-%d' "$d" "+%Y, %V, %F, $v"; done < inp
2016, 53, 2016-01-01, 5
2016, 01, 2016-01-09, 15
2016, 05, 2016-02-01, 3.14

这会将所有内容弹出到date 命令的格式中,从而避免需要子shell 或临时变量。

注意引号的选择。虽然格式字符串通常被认为是静态的,并且通常放在单引号中,但如果我们想在格式中包含变量$v,我们必须使用双引号来代替,以便进行变量扩展。请注意,如果由于某种原因,您在 CSV 中的输入数据是“脏”的,您可能很容易中断您的处理,因为除了 date 解析第一个字段的能力之外,这不提供任何输入检查。


更新

如果您使用MacportsBrewetc 在您的系统上安装 GNU awk (gawk),那么以下可能会执行得更好:

gawk 'BEGIN{OFS=FS=", "} {split($1,a,"-"); print a[1],strftime("%V",mktime(gensub(/-/," ","g",$1) " 00 00 00")),$1,$2}' inp

我把这篇文章写成单行的,但为了更容易解释,我会打破要点。

  • BEGIN { OFS=FS=", " } - 在脚本的开头,定义一个字段分隔符。
  • { - 此 awk 脚本的主要部分没有“条件”,因此将对每一行输入执行。
  • split($1,a,"-") - 将第一个字段拆分为数组a[],用连字符分隔。
  • print a[1], - 打印输出,从年份开始,
  • strftime("%V", - 后跟一年中一周的时间格式,
  • mktime(gensub(/-/," ","g",$1) " 00 00 00")) - 从以 mktime 的“datespec”格式解析的时间生成,
  • ,$1,$2} - 后跟其他两个字段。

我还没有制定任何性能指标,但我确信自包含 gawk 选项的运行速度明显快于基于 bash 的选项,后者为每行输入生成一个 date 命令。

【讨论】:

  • @l'L'l - OP 描述的输入数据中没有反斜杠。
  • @l'L'I - 文件中的数据非常干净。我不必担心任何异常处理。
  • @ghoti - 你的解决方案效果很好......除了......我没有提到一个非常重要的细节。即数据文件巨大,处理时间较长。该文件有 620,000 行,所以也许我选择的 date 命令不是正确的方法?您对如何处理这个问题还有其他想法吗?
  • 好吧,在 OSX 的 bash 中没有额外的工具,不。 Bash 没有内部日期修改功能,它只是一个外壳。很可能不是date 命令很慢,而是为每一行输入运行一个新的date 命令所需的努力。您可能可以使用 strptime 和 strftime 在 perl 或 python 甚至在 C 中做一些更有效的事情,但这完全超出了这个问题的范围。 :-)
  • @ghoti - 是的,我会考虑使用另一种语言。不过,我仍会将您的第一个回复标记为答案,因为它确实有效。谢谢!
猜你喜欢
  • 2011-04-27
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 2011-02-08
相关资源
最近更新 更多