重组此csv的最简单方法是什么?

问题描述 投票:0回答:2

我有一个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之类的文件处理工具就可以轻松地做到这一点?

csv awk sed etl
2个回答
0
投票

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。


0
投票
$ 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?。>

© www.soinside.com 2019 - 2024. All rights reserved.