在 CSV 上就地转换列

在 CSV 上就地转换列

我需要一些有关 CSV 上日期转换的帮助。基本上,我能够转换列并保存在新文件中,但无法将其保存在原始 CSV 中。

我有一个带有日期格式的 CSV DD/MM/YYYY HH:MM,我想转换为YYYY-MM-DD HH:MM,它是我的 CSV 的第一列。

我的 CSV 文件有类似的内容:

29/01/2018 14:07,payable,37159871,,30521316
29/01/2018 14:07,payable,37159872,,30521316
29/01/2018 14:07,payable,37159870,,30521316
29/01/2018 14:07,payable,37159869,,30521316
29/01/2018 14:07,payable,37159868,,30521316

我想要这样的东西:

2018-01-29 14:07,payable,37159871,,30521316
2018-01-29 14:07,payable,37159872,,30521316
2018-01-29 14:07,payable,37159870,,30521316
2018-01-29 14:07,payable,37159869,,30521316
2018-01-29 14:07,payable,37159868,,30521316

我能做的:

gawk -F, '{split($1, a, "/| "); print a[3]"-"a[2]"-"a[1]" "a[4]}' /path/to/file.csv > test_file

所以现在我想知道如何将其保存回我的 CSV 文件中。

答案1

本例中的编辑非常简单,我不会费心使用 Awk。

使用 GNU Sed 就这么简单:

sed -rie 's_^(..)/(..)/(....)_\3-\2-\1_' file.csv

对于 BSD Sed,请使用:

sed -Ei '' -e 's_^(..)/(..)/(....)_\3-\2-\1_' file.csv

仅使用 POSIX 工具,它会有点丑陋,但并不可怕:

printf '%s\n' '%s/^\(..\)\/\(..\)\/\(....\)/\3-\2-\1/' x | ex file.csv

编辑:实际上仔细看看POSIX 规范ex表明可以使用(几乎)任何分隔符,就像在 Sed 中一样。所以:

printf '%s\n' '%s_^\(..\)/\(..\)/\(....\)_\3-\2-\1_' x | ex file.csv

轻微地更好的。

答案2

鉴于 awk 没有内置的“就地编辑”选项(通常通常作为幕后副本实现),并且自从阅读这个答案,在这种情况下我的首选解决方案是:

cp 输入文件临时文件 && 命令 … 临时文件 > 输入文件 && rm 临时文件

针对您的情况:

cp /path/to/file.csv temp_file &&
gawk -F, '{split($1, a, "/| "); print a[3]"-"a[2]"-"a[1]" "a[4]}' < temp_file > /path/to/file.csv &&
rm temp_file

请注意&&将命令绑定在一起并仅在前面的命令成功时才执行后续命令的语法。

答案3

由于您使用的是 GNU awk:

gawk -i inplace -F, ...

如果您想保留原始文件的备份

gawk -i inplace -v INPLACE_SUFFIX=".bak" -F, ...

https://www.gnu.org/software/gawk/manual/html_node/Extension-Sample-Inplace.html#Extension-Sample-Inplace

答案4

我通过使用下面的 awk 命令实现了相同的效果

输入.csv

2018-01-29 14:07,payable,37159871,,30521316
2018-01-29 14:07,payable,37159872,,30521316
2018-01-29 14:07,payable,37159870,,30521316
2018-01-29 14:07,payable,37159869,,30521316
2018-01-29 14:07,payable,37159868,,30521316

命令

awk '{gsub("/","-",$0);print $0}' input.csv| awk -F "-" '{print $3,$2,$1}'  | awk -F " " '{print $1"-"$(NF -1)"-"$NF,$2}'

输出

2018-01-29 14:07,payable,37159871,,30521316
2018-01-29 14:07,payable,37159872,,30521316
2018-01-29 14:07,payable,37159870,,30521316
2018-01-29 14:07,payable,37159869,,30521316
2018-01-29 14:07,payable,37159868,,30521316

相关内容