如何将特定列中的文件 csv 日期转换为 unix 日期

How to convert in file csv date in specific column to unix date

我有一个包含以下列的 csv 文件:

"Weight","Impedance","Units","User","Timestamp","PhysiqueRating"
"58.75","5.33","kg","7","2020-7-11 19:29:29","5"

当然,我可以转换日期命令: date -d '2020-7-11 19:29:29' +%s

结果: 1594488569

如何在 bash 脚本中替换 csv 文件中的这个日期?

使用 GNU awk:

$ gawk '
BEGIN {
    FS=OFS=","
}
{
    n=split(,a,/[-" :]/)
    if(n==8)
        ="\"" mktime(sprintf("%s %s %s %s %s %s",a[2],a[3],a[4],a[5],a[6],a[7])) "\""
}1' file

输出:

"Weight","Impedance","Units","User","Timestamp","PhysiqueRating"
"58.75","5.33","kg","7","1594484969","5"

GNU sed

sed -E '2,$ s/(("[^"]*",){4})("[^"]+")(.*)/echo \x27"\x27$(date -d  +%s)\x27"\x27/e'
  • 2,$ 跳过 header 处理
  • (("[^"]*",){4})前四列
  • ("[^"]+")第五栏
  • (.*) 其余行
  • echo \x27"\x27\x27"\x27 保留前四列和第五列之后的剩余行,同时为日期转换结果添加双引号
  • $(date -d +%s) 使用第五列值调用 shell 命令

请注意,如果输入可以包含单引号,则此命令将失败。这可以通过使用 s/\x27/\x27\&\x27/g.

来解决

您可以看到使用 -n 选项和 pe 标志执行的命令

sed -nE '2,$ s/(("[^"]*",){4})("[^"]+")(.*)/echo \x27"\x27$(date -d  +%s)\x27"\x27/pe'

会给

echo '"58.75","5.33","kg","7","'$(date -d "2020-7-11 19:29:29" +%s)'","5"'


对于58.25,5.89, kg, 7,2020 / 7/12 11:23:46, "5"格式,尝试

sed -E '2,$ s/(([^,]*,){4})([^,]+)(.*)/echo \x27\x27$(date -d "" +%s)\x27\x27/e'

或(改编自https://whosebug.com/a/62862416

awk 'BEGIN{FS=OFS=","} NR>1{=mktime(gensub(/[:\/]/, " ", "g", ))} 1'


注意: 对于 sed 解决方案,如果输入可以来自外部源,则必须注意避免恶意意图,如注释。一种方法是使用 [0-9: -]+ 或类似方法匹配第五列。

对于 gensub() 和 mktime() 使用 GNU awk:

$ awk 'BEGIN{FS=OFS="\""} NR>1{=mktime(gensub(/[-:]/," ","g",))} 1' file
"Weight","Impedance","Units","User","Timestamp","PhysiqueRating"
"58.75","5.33","kg","7","1594513769","5"