TOKENIZE
и FLATTEN
могут помочь вам здесь. Оператор TOKENIZE
в Pig берет строку и разделитель, разбивает строку на части на основе разделителя и складывает части в пакет. Оператор FLATTEN
в Pig берет сумку и взрывает каждый элемент в сумке в новую запись. Код будет выглядеть следующим образом:
--Load you initial data and split into columns based on ':'
data = LOAD 'path_to_data' USING PigStorage(':') AS (index:long, name:chararray, genres:chararray);
--Split & Explode each individual genre into a separate record
dataExploded = FOREACH data GENERATE FLATTEN(TOKENIZE(genres, '|')) AS genre;
--GROUP and get counts for each genre
dataWithCounts = FOREACH (GROUP dataExploded BY genre) GENERATE
group AS genre,
COUNT(dataExploded) AS genreCount;
DUMP dataWithCounts;
Нет никакой причины, Вы не могли загрузить копию текста:: CSV или любой другой non-XS основывал реализацию синтаксического анализатора CSV, и установите его в своем локальном каталоге, или в lib / подкаталог Вашего проекта так его установленный наряду с Вашим развертыванием проектов.
Если Вы не можете сохранить текстовые файлы в своем проекте, то я задаюсь вопросом, как это - Вы, кодируют Ваш проект.
http://novosial.org/perl/life-with-cpan/non-root/
Должно быть хорошее руководство по тому, как получить их в рабочее состояние локально.
Рассмотрите это прежде, чем попытаться записать Вашу собственную реализацию CSV.
Текст:: CSV является более чем ста строками кода, включая исправленные ошибки и пограничные случаи, и переписывающий это с нуля просто заставит Вас изучить, как ужасный CSV может быть твердым путем.
примечание: Я изучил это твердый путь. Взял меня целый день для получения рабочего синтаксического анализатора CSV в PHP, прежде чем я обнаружил, что встроенный был добавлен в более поздней версии. Это действительно - что-то ужасное.
Можно проанализировать CSV с помощью текста:: ParseWords, который поставлется с Perl.
use Text::ParseWords;
while (<DATA>) {
chomp;
my @f = quotewords ',', 0, $_;
say join ":" => @f;
}
__DATA__
COLLOQ_TYPE,COLLOQ_NAME,COLLOQ_CODE,XDATA
S,"BELT,FAN",003541547,
S,"BELT V,FAN",000324244,
S,SHROUD SPRING SCREW,000868265,
S,"D" REL VALVE ASSY,000771881,
S,"YBELT,"V"",000323030,
S,"YBELT,'V'",000322933,
который анализирует Ваш CSV правильно....
# => COLLOQ_TYPE:COLLOQ_NAME:COLLOQ_CODE:XDATA
# => S:BELT,FAN:003541547:
# => S:BELT V,FAN:000324244:
# => S:SHROUD SPRING SCREW:000868265:
# => S:D REL VALVE ASSY:000771881:
# => S:YBELT,V:000323030:
# => S:YBELT,'V':000322933:
Единственная проблема я имел с текстом:: ParseWords - когда вложенных кавычек в данных не оставляют правильно. Однако это - плохо созданные данные CSV и вызвало бы проблемы с большинством синтаксических анализаторов CSV ;-)
Таким образом, можно заметить это
# S,"YBELT,"V"",000323030,
вышел как (т.е. кавычки, отброшенные приблизительно "V")
# S:YBELT,V:000323030:
однако, если его завершенное как так
# S,"YBELT,\"V\"",000323030,
затем кавычки будут сохранены
# S:YBELT,"V":000323030:
Нахождение соответствия парам с помощью regexs является нетривиальной и обычно неразрешимой задачей. Существует много примеров в книге регулярных выражений Освоения Jeffrey Friedl. У меня нет его под рукой теперь, но я помню, что он использовал CSV для некоторых примеров, также.
Вы можете (попробовать к), используют CPAN.pm, чтобы просто иметь Ваш текст установки/обновления программы:: CSV. Как сказано прежде, можно даже "установить" его на домашнем или локальном каталоге и добавить, что каталог к @INC (или, если Вы предпочитаете не использовать BEGIN
блоки, Вы можете use lib 'dir';
- это, вероятно, лучше).
Проверено:
use Test::More tests => 2;
use strict;
sub splitCommaNotQuote {
my ( $line ) = @_;
my @fields = ();
while ( $line =~ m/((\")([^\"]*)\"|[^,]*)(,|$)/g ) {
if ( $2 ) {
push( @fields, $3 );
} else {
push( @fields, $1 );
}
last if ( ! $4 );
}
return( @fields );
}
is_deeply(
+[splitCommaNotQuote('S,"D" REL VALVE ASSY,000771881,')],
+['S', '"D" REL VALVE ASSY', '000771881', ''],
"Quote in value"
);
is_deeply(
+[splitCommaNotQuote('S,"BELT V,FAN",000324244,')],
+['S', 'BELT V,FAN', '000324244', ''],
"Strip quotes from entire value"
);