Разделить этот csv / xls на отдельные файлы на основе двух столбцов?

#excel #bash #csv #split #kettle

#excel #bash #csv #разделить #чайник

Вопрос:

У меня есть файл Excel размером 35 МБ с этими столбцами:

 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. (Альтернативы также приветствуются.)

Ответ №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 путаются).

2. @Dimitre Radoulov: Спасибо за ваш сценарий. Однако он выдает эту ошибку: «awk: недопустимый оператор в исходной строке 1».

3. @dani, какую операционную систему и версию awk вы используете? Не могли бы вы опубликовать точную команду, которую вы выполняете?

4. @Dimitre Radoulov: Дорогой Дмитрий, я поместил это в файл .sh: awk -F, ‘NR ==1{title = $ 0;next} { print > $ 2″.csv»}’ clean_1950_2100_TEST.csv. Я использую Mac OS 10.6 с awk версии 20070501. Спасибо.

5. @dani, это не мой код 🙂 В любом случае, чтобы исправить ошибку, которую вам нужно изменить print > $2".csv" print > ($2".csv") .

Ответ №2:

Если awk является приемлемым, экспортируйте в csv и выполните следующую команду:

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

Сообщите, если вы:

  1. Хотите сохранить строку заголовка во всех файлах.
  2. Выдает ошибки из-за слишком большого количества открытых файлов.

Для сортировки файла за пределами Excel:

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

Редактировать: это решит большинство проблем (за исключением одновременно открытых файлов):

 {
  read
  printf '%sn' "$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 
  

Комментарии:

1. Если мы закроем (f), то нам понадобится «>>», иначе вы получите только одну строку в каждом файле. (последняя строка)

2. Привет @Kent, да, в этом случае нам нужен double >>.