【问题标题】:What's the easiest way to restructure this csv?重组这个 csv 最简单的方法是什么?
【发布时间】:2019-11-07 00:43:53
【问题描述】:

我有一个 csv 文件,其中包含我要转换的不同行上的客户端数据。

当前布局为:

Client_Name,Client_ID,Client_Group,Attribute_Name,Date,Attribute_Value

每一行都包含有关客户的信息,例如:

Acme,0001,Marketing,Sales_Amt,2010-10-01,100
Acme,0001,Marketing,Queries,2010-10-01,3
Smiths,0002,Retail,Sales_Amt,2010-10-01,1200
Smiths,0002,Retail,Queries,2010-10-01,11

我想做的是将其转换为以下时间序列布局:

Date,Client_Name,Sales_Amt,Queries

这样每一行都写成:

2010-10-01,Acme,100,3
2010-10-01,Smiths,1200,11

所以我可以每天查看每个客户的属性。这是 ETL 的工作吗?或者我可以使用 sed 和 awk 等文件操作工具轻松完成这项工作吗?

【问题讨论】:

  • 对于 awk 来说听起来微不足道。您只需要知道如何设置字段分隔符以及如何打印字段
  • 相关行总是相邻的吗?
  • 并且同一个文件中会有多天的数据吗?或者你每天有 1 个文件?而是在 cmets 中回复,请使用此重要信息(及以上)更新您的 Q。祝你好运。

标签: csv awk sed etl


【解决方案1】:
$ cat tst.awk
BEGIN { FS=OFS="," }
{
    sub(/\r$/,"")
    curr = $5 OFS $1
}
curr != prev {
    if ( NR > 1 ) {
        print prev, vals[1], vals[2]
    }
    prev = curr
    cnt = 0
}
{ vals[++cnt] = $NF }
END {
    print prev, vals[1], vals[2]
}

$ awk -f tst.awk file
2010-10-01,Acme,100,3
2010-10-01,Smiths,1200,11

有关使用 awk 解析 CSV 的更多信息,请参阅 What's the most robust way to efficiently parse CSV using awk?

【讨论】:

    【解决方案2】:

    Perl 和它的 Text::CSV_XS 来救援!

    perl -MText::CSV_XS=csv -we '
        csv(in    => shift,
            on_in => sub { $h{ $_[1][4] }{ $_[1][0] }[ $_[1][3] eq "Queries" ] = $_[1][5] },
            out   => \"skip");
        csv(in => [ map { $x = $_;
                          map [$x, $_, @{ $h{$x}{$_} } ],
                          sort keys %{ $h{$_} }
                    } sort keys %h ]);
    ' -- file.csv
    

    它首先用您要保留的数据填充一个哈希%h,然后将其输出为一个新的 csv。

    【讨论】:

      猜你喜欢
      • 2012-07-28
      • 2016-09-04
      • 2014-05-17
      • 2015-06-26
      • 1970-01-01
      • 2021-11-11
      相关资源
      最近更新 更多