Разделить этот CSV / XLS на отдельные файлы на основе двух столбцов? - PullRequest
1 голос
/ 05 октября 2011

У меня есть 35-мегабайтный файл Excel с этими столбцами:

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 или Kettle /Решение Pentaho будет высоко ценится.(Альтернативы также приветствуются.)

Ответы [ 2 ]

2 голосов
/ 05 октября 2011

Я просто использовал пример данных, которые вы вставили туда.

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
0 голосов
/ 05 октября 2011

Если приемлем 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 
...