2011-10-05 145 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,是的,在這種情況下,我們需要雙倍>>。 –

相關問題