2011-10-05 103 views
1

我有一个35 MB的Excel与这些列文件:根据两列将此csv/xls拆分为单独的文件?

Index, Name, Year, AgeGroup1, AgeGroup2, AgeGroup3 [...] 
1, Sweden, 1950, 20, 25, 27 
2, Norway, 1950, 22, 27, 28 
2, Sweden, 1951, 24, 24, 22 

我想将文件分割成基于“名称”列(基于价值最好也命名文件多个CSV文件,在本专栏中)。
我也想按“年”排序文件(但这当然可以在Excel中预先完成)。

bash脚本或水壶/ Pentaho解决方案将不胜感激。 (替代方案也是受欢迎的。)

回答

1

我刚刚使用了粘贴在那里的示例数据。

AWK oneliner能为你做到这一点:

awk -F, 'NR==1{title=$0;next} { print >> ($2".csv");colse}' yourCSV 

见下面的测试:

kent$ l 
total 4.0K 
-rw-r--r-- 1 kent kent 136 2011-10-05 11:04 t 

kent$ cat t 
Index, Name, Year, AgeGroup1, AgeGroup2, AgeGroup3 
1, Sweden, 1950, 20, 25, 27 
2, Norway, 1950, 22, 27, 28 
2, Sweden, 1951, 24, 24, 22 


kent$ awk -F, 'NR==1{title=$0;next} { print >> $2".csv"}' t 

kent$ head *.csv 
==> Norway.csv <== 
2, Norway, 1950, 22, 27, 28 

==> Sweden.csv <== 
1, Sweden, 1950, 20, 25, 27 
2, Sweden, 1951, 24, 24, 22 

更新

awk -F, 'NR>1{ fname=$2".csv"; print >>(fname); close(fname);}' yourCsv 
+1

两条评论:1.在awk中,在大多数情况下,你不需要double >>来追加。在这种情况下,你不需要。 2.使用没有圆括号的重定向是不可移植的(一些awk实现会变得困惑)。 –

+0

@Dimitre Radoulov:谢谢你的剧本。但是它给出了这个错误:“awk:源代码行1的非法声明”。 – dani

+0

@dani,您正在使用哪种操作系统和* awk *版本?你能发布你正在运行的确切命令吗? –

0

如果AWK是可以接受的,出口到CSV并运行以下命令:

awk -F, '{ 
    print > ($2 ".csv") 
    }' OFS=, infile.csv 

报告回来,如果你:

  1. 要保留头在所有文件中都行。
  2. 由于打开的文件太多而获取错误。

要排序的Excel以外的文件:

sort -t, -k3,3n infile.csv | awk ... 

编辑:这会照顾大多数问题(除了同时打开的文件):

{ 
    read 
    printf '%s\n' "$REPLY" 
    sort -bt, -k3,3 
    } < infile | 
    awk -F', *' 'NR == 1 { 
     h = $0; next 
     } 
    { 
     f = $2 ".csv" 
     if (!_[f]++) 
     print h > f 
     print > f 
     }' OFS=', ' 

如果您击中你的awk实现的“太多打开的文件”的限制,你可以使用这样的东西:

awk -F, 'NR > 1 { 
    if (f) close (f) 
    f = $2 ".csv" 
    print > f 
    }' OFS=, infile 
+0

如果我们关闭(F),那么我们就需要“>>”,否则你只能在每个文件中获得一行。 (最后一行) – Kent

+0

嗨@Kent,是的,在这种情况下,我们需要双倍>>。 –

相关问题