将 csv 表中的日期重新格式化为 unix 时间戳

将 csv 表中的日期重新格式化为 unix 时间戳

我有一个包含第一列.csv格式的日期和时间的文件。01/20/2016 23:53:01我的列用分号分隔,即

01/21/2016 03:03:01;18616;0;1
01/21/2016 03:13:01;29040;36553;2

所以我找到了 bash 命令

date -d '06/12/2012 07:21:22' +"%s" 

这适用于我想要的。我现在一直在尝试集成awk以替换第一列。我找到了一个回答类似问题:

awk -F'"' -v OFS='"'  '$8 {cmd="date -d \""$8"\" +%FT%T%z"; cmd | getline $8; close(cmd)} 1' input.json

我试图适应我自己的输入。但我得到的输出是空的。

答案1

我终于在写问题时避开了它。所以这是我的解决方案:

awk -F';' -v OFS=';'  '$1 {cmd="date -d \""$1"\" +%s"; cmd | getline $1; close(cmd)} 1' datetime.csv > unix.csv

这是两件事的结合:我错过了开启"+%s"并且我的输入中有一条断线。

答案2

GNU date 有一个-f选项可以逐行转换从文件中读取的日期。如果您的文件很长,这将比date每行调用一次更快。日期需要单独就行;因此计划是隔离第一列 ( cut -d \; -f 1),运行它date -f -以执行转换,并且粘贴剩余列的结果。

paste -d \; <(<input cut -d \; -f 1 | date -f - +%s) <(<input cut -d \; -f 2-)

这假设您的 shell 支持流程替代(ksh93、bash、zsh)。对于 plain sh,在支持(大多数支持)的 Unix 变体上/dev/fd,您可以使用文件描述符改组:

<input cut -d \; -f 2- | {
  exec 3<&0
  <input cut -d \; -f 1 | date -f - +%s | paste -d \; - /dev/fd/3
}

答案3

嗯嗯。好吧,这是不久前的事,但我想不妨提出一个建议。

我相当确定,如果您有很多行,那么进入 shell 为文件的每一行调用“date”可能会有点慢。

我打算编写一个脚本来处理从 Google 日历中提取的时间表条目,并输出一些 HTML,然后转换为 PDF 发票。但后来谈论这个话题就太长了。所以我只是给你代码以节省阅读时间。

我正在使用 AWK 函数 gensub 和 mktime [https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html]。 mktime 函数需要 datespec 格式的输入“YYYY MM DD HH MM SS [DST]”,因此您的输入需要在 gensub 函数所在的位置移动。这是我为您提供的...

awk -F';' -v OFS=';' '{ $1=mktime(gensub(/(..)\/(..)\/(....) (..):(..):(..)/, "\\3 \\1 \\2 \\4 \\5 \\6", 1, $1)); } 1' datetime.csv > unix.csv

我会采取稍微不同的做法,并在打印中输出各个参数,而不是写回第一个参数。多一点自我记录;) 蒂姆托维迪

awk -F';' -v OFS=';' '{ print mktime(gensub(/(..)\/(..)\/(....) (..):(..):(..)/, "\\3 \\1 \\2 \\4 \\5 \\6", 1, $1)), $2, $3, $4; }' datetime.csv > unix.csv

我知道该脚本有点冗长,但希望它的性能更高。

希望这对您或其他看到同样事情的人有所帮助。

相关内容