2012-11-28 5 views
0

Как слить несколько файлов CSV в perl?слить несколько файлов CSV perl

Например, у меня есть файл 1 Packet1.csv выглядит как:

#type, number, info, availability 
computer, t.100, pentium 2, yes 
computer, t.1000, pentium 3, yes 
computer, t.2000, pentium 4, no 
computer, t.3000, pentium 5, yes 

и файл 2 Packet2.csv выглядит как:

#type, number, info, availability 
computer, t.100, pentium 2, yes 
computer, t.1000, pentium 3, no 
computer, t.2000, pentium 4, no 
computer, t.4000, pentium 6, no 

и выход я желаю это единый файл, где число Пакеты не фиксировано:

#type, number, info, **Packet1** availability, **Packet2** availability 
computer, t.100, pentium 2, yes, yes 
computer, t.1000, pentium 3, yes, no 
computer, t.2000, pentium 4, no, no 
computer, t.3000, pentium 5, yes 
computer, t.4000, pentium 6, no 
+0

Сколько у вас данных? Можно ли загружать все в память? Ваш вход всегда отсортирован, как в примере? – pmakholm

+1

@Tim N Я пробовал использовать многомерные хэши – TheBlackCorsair

+0

@ TheBlackCorsair Почему это не сработало? – Tim

ответ

3

Возвращаясь к вашей попытке многомерного хэширования: Hash of hashes perl, вам нужно будет изменить структуру данных, которую вы используете, чтобы хранить несколько записей определенного элемента.

CSVs можно интуитивно прочитать в хэш с 2 уровнями. Строки csv можно хэшировать по их идентификаторам (в этом случае я думаю, что идентификаторы представляют собой числа «t.100», «t.1000» и т. Д.), А значения каждой строки могут быть сохранены в хэшере второго уровня, используя строки заголовка в качестве его ключей. Это будет выглядеть примерно так, если рассматривать структуру с Data :: Dumper:

$VAR1 = { 
      't.1000' => { 
         'info' => 'pentium 3', 
         'availability' => 'yes', 
         'type' => 'computer' 
         }, 
      't.100' => { 
         'info' => 'pentium 2', 
         'availability' => 'yes', 
         'type' => 'computer' 
        } 
     }; 

«число», является ли ключ для каждой строки «хэш» до вас, в зависимости от того, насколько полезным это может быть (обычно вы уже знаете ключ для строки, чтобы получить к нему доступ).

Эта структура данных будет в порядке, чтобы сохранить один файл CSV. Однако нам нужно добавить дополнительный уровень сложности, чтобы справиться с объединением нескольких CSV в том, как вы описываете. Например, чтобы отслеживать файлы, в которых находится определенный идентификатор, мы можем хранить третий хеш в качестве значения ключа «доступности», поскольку это значение, которое изменяется между записями одного и того же «числа»:

'availability' => { 
      'Packet1' => 'yes', 
      'Packet2' => 'no' 
     }; 

После того, как все файлы были прочитаны в эту структуру, выводя окончательный CSV из затем процесса зацикливания ключей от внешнего хэша и для каждой строки, «присоединение» ключей в строке и в правильном порядке , Хэш «Пакет» также можно зацикливать, чтобы получить все значения «доступности», и их можно добавить в конец каждой строки.

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

+0

Мне нравится этот ответ. +1 – mpe

+0

спасибо @kikumbob, я дам ему попробовать, и я дам вам знать – TheBlackCorsair

0
  • Как вы определяете, какой компьютер является? Вы зависите от первых трех полей как идентификация компьютера?
  • Что делать, если первое поле не computer?
  • Что произойдет, если два файла не согласятся с типом компьютера?

Вам действительно нужно ответить на эти вопросы, прежде чем вы сможете выяснить, как с этим справиться. Однако вам, вероятно, придется иметь дело с references.

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

Например, предположу, что у вас есть хэш с именем % компьютером что ключ к этому второму полю:

my %system; 

$system{t.100} = {} #This is a hash of hashes 
$system{t.100}->{INFO} = "pentium 2"; 
$system{t.100}->{TYPE} = "computer"; 
$computer{t.100}->{AVAILABLITY} = [] #Storing an array in this hash entry (hash of hashes of arrays) 
$computer{t.100}->{AVAILABILITY}->[0] = "yes"; 
$computer{5.100}->{AVAILABILITY}->[1] = "yes"; 

Вы также мог бы использовать push и pop по Разыменованием массива:

push @{ $computer{t.100}->{AVAILABILITY} }, "yes"; 

Обратите внимание, что я окружил ссылку на массив $computer{t.100}->{AVAILABILITY} с помощью @{...}, и он превращается из рефери перейдите к массиву обратно в массив.

Надеюсь, это то, о чем вы просите. Вы можете использовать модуль Text::CSV для анализа файла CSV, но если формат не слишком пухлый, возможно, вы можете просто использовать команду split.

Смежные вопросы