2014-12-08 2 views
0

У меня есть несколько файлов CSV в каталоге, все с той же моделью данных, некоторые из которых дублируются.Как объединить несколько CSV-файлов в один, с уникальными значениями

file1.csv:

1  joe  red 
2  bill  blue 
3  bob  green 

file2.csv:

3  bob  green 
4  mary  white 
5  jim  yellow 

file3.csv:

5  jim  yellow 
6  lauren pink 
7  george purple 

Моя цель состоит в том, чтобы произвести один CSV файл все уникальные значения.

До сих пор код у меня есть это:

  1. Каскадные все файлы в iTerm2 используя

    cat *.csv > combined.csv 
    
  2. И этот сценарий:

    require 'csv' 
    
    File.open("all_unique_rows.csv", "w+") { 
    
        |file| file.puts File.readlines("combined.csv").uniq 
    
    } 
    

Однако , Я хочу быть в состоянии сделать это al l из одного скрипта Ruby, однако я просто не уверен, как сделать файл «combined.csv» одним гигантским файлом с помощью Ruby.

+0

Это не файлы CSV. Скорее всего, они фиксированные, но могут быть TSV, хотя ваш третий образец имеет перекошенные столбцы для последних двух записей. –

ответ

4

Я бы не сделал этого в Ruby, если ваши записи являются истинными дубликатами. Вместо этого, воспользоваться существующими инструментами в ОС, для этого:

cat *.csv | sort -u >unique.csv 

Когда закончите, «unique.csv» будет содержать уникальные записи.

Если вы настаиваете на написании его в Ruby, воспользуйтесь встроенными методами или классами. Вот один непроверенный способ сделать это:

require 'set' 
unique = Set.new 
Dir.glob('*.csv') do |f| 
    File.foreach(f) { |l| unique << l } 
end 
File.write('unique.csv', unique.sort.join) 

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

Альтернативный способ сделать что-то вроде:

unique = [] 
Dir.glob('*.csv') do |f| 
    unique += File.readlines(f) 
end 
File.write('unique.csv', unique.sort.uniq.join) 

В то время как Руби может сделать это, используя операционную систему, чтобы справиться с гораздо более масштабируемым. YMMV.


Я попытался запустить кошку * .csv | sort - u> unique.csv в ОС, но в итоге некоторые значения ошибочно вошли в неправильные столбцы.

Я создал три файла на моем диске:

 
$ cat file1.csv 
1  joe  red 
2  bill  blue 
3  bob  green 
 
$ cat file2.csv 
3  bob  green 
4  mary  white 
5  jim  yellow 
 
$ cat file3.csv 
5  jim  yellow 
6  lauren pink 
7  george purple 

Бег cat *.csv | sort -u >unique.csv и глядя на полученный файл показывает:

 
$ cat unique.csv 
1  joe  red 
2  bill  blue 
3  bob  green 
4  mary  white 
5  jim  yellow 
6  lauren pink 
7  george purple 

Дубликаты удаляются, и файл идентичен входным образцам, которые вы дали. Ваш «file3.csv» показывает дополнительное пространство в последних линиях, нажав верхний столбец справа.

Примечание: Ваши файлы NOT CSV-файлы. CSV означает «значения, разделенные запятыми», и между вашими столбцами нет запятых. Возможно, изначально у вас был TSV («значения, разделенные табуляцией»), которые Ruby CSV-класс может читать и писать, или у вас есть столбцы фиксированной ширины и каким-то образом добавлено дополнительное пространство. Очень важно использовать правильную терминологию и делать это последовательно, особенно при задании вопросов.

+0

Что делает '{| l | уникальный << l} 'do? –

+0

Я попытался запустить 'cat * .csv | sort - u> unique.csv' в ОС, но в итоге некоторые значения ошибочно вошли в неправильные столбцы. –

+0

Если они находятся в неправильных столбцах, проверьте входные файлы. В командах ОС нет ничего, что могло бы изменить столбцы. Эти команды работают только на полных строках. –