我有一个包含几十万行的 csv,我正在尝试更改第二个字段中的日期格式。我还应该添加第二个字段有时根本没有填充。可悲的输入格式是DayofWeek MonthofYear DayofMonth Hour:Minute:Second Timezone Year
例子:
Mon Jul 03 14:48:54 EDT 2023
我想要的输出格式是YYYY-MM-DD HH:MM:SS
示例:
2023-07-03 14:48:54
我熟悉 sed,所以我得到了这个 sed 正则表达式替换行以使其格式几乎正确,但月份不是数字是一个问题。
sed -E "s/[A-Za-z]{3}\s([A-Za-z]{3})\s([0-9]{2})\s([0-9]{2}:[0-9]{2}:[0-9]{2})\s[A-Z]+\s([0-9]{4})/\4-\1-\2 \3/"
我认为不可能使用捕获组 1 在 sed 替换部分中运行 date 命令(但如果我错了,请纠正我)。
我不知道如何在 sed 命令完成后引用月份并使用 date 命令解析它,并且我认为最好在不将整个输出通过管道传输到另一个命令的情况下进行处理。该命令只是用于格式化其余数据的一长串管道命令中的一个。
看起来也许 awk 可以一次完成整个格式化,但我真的不知道如何很好地使用 awk。
将时间戳转换为正确格式的最有效方法是什么?
只是为了解决一些带有更多背景信息的评论:
此数据由将 csv 日志数据输出到文件的应用程序生成。这不是我的应用程序,并且没有对应用程序日志记录方式的配置控制。CSV 未引用(即使字段中的数据包含空格)并且空字段不包含任何内容。
我将 csv 数据直接加载到 mysql 数据库中。虽然时区通常是一个好主意,但该数据始终带有本地时间时间戳,并且在可视化数据(grafana)时,我不需要将其存储在 UTC 中,然后转换为 EDT 只是为了查看(为什么将时间转换为 UTC只是将其转换回 EDT)。另外,每个 csv 行都包含经度和纬度(因此,如果我想返回并将时间戳更改为 UTC,则不可能找出当地时间)。
我所做的额外格式化并不多,可能可以使用 awk 完成(同样,我不太熟悉那里的语法)。原始数据需要添加 ID 列,并且 qoutes 放置一些字段,并且有两种不同格式的两个日期时间字段,这并没有帮助。所以我的又长又可怕的管道通常看起来像这样:
cat file | add ID column | format timestamp in second csv field | format timestamp in third csv field | qoute any field with spaces | replace empty fields with \N > output file
我在 mysql 和空字段方面遇到了一些问题,所以我添加了显式的空字符。肯定有更好的方法来做到这一点,一旦我让整个过程正常工作,我将回顾并简化。
我非常感谢大家的回应。