2015-06-08 3 views
-3

У меня есть входной файл, подобный этому (3 столбца). Различные элементы также присутствуют в каждой строке .. соответствующий а .. б .. и с ...Как считать каждую запись из каждого столбца, соответствующего поисковому запросу

a sk asd     
a sk lsd     
a mk wsd     
a lk asd     
a lk lsd     
a pk wsd     
a pk asd     
b sk lsd     
b sk wsd     
b mk asd     
b lk lsd     
b lk wsd     
c sk asd     
c sk lsd     
c mk wsd     
c lk asd     
c lk lsd     
d sk wsd     
d sk asd     
d mk lsd 

Я хочу написать программу Perl, который, первым сосчитать а, б, в и г. и затем подсчитывать каждую запись, соответствующую а, b, c и d.

Вывод будет выглядеть следующим образом ..

a=7 sk=2 mk=1 lk=2 pk=2 asd=3 lsd=2 wsd=2  
b=5 sk=2 mk=1 lk=2 pk=0 asd=1 lsd=2 wsd=2  
c=5 sk=2 mk=1 lk=2 pk=0 asd=2 lsd=2 wsd=1 
d=3 sk=2 mk=1 lk=0 pk=0 asd=1 lsd=1 wsd=1 

Как я могу сделать это. Пожалуйста помоги ?

ответ

1

Как это:

#!/usr/bin/perl 
use strict; 
use warnings; 

my %count_elements_of; 
my %count_of; 

while (<DATA>) { 
    my ($term, @things) = split; 
    $count_of{$term}++; 
    foreach my $thing (@things) { 
     $count_elements_of{$term}{$thing}++; 
    } 
} 

foreach my $term (sort keys %count_elements_of) { 
    print "$term => $count_of{$term}, "; 
    foreach my $thing (sort keys %{ $count_elements_of{$term} }) { 
     print "$thing => $count_elements_of{$term}{$thing}, "; 
    } 
    print "\n"; 
} 


__DATA__ 
a sk asd 
a sk lsd 
a mk wsd 
a lk asd 
a lk lsd 
a pk wsd 
a pk asd 
b sk lsd 
b sk wsd 
b mk asd 
b lk lsd 
b lk wsd 
c sk asd 
c sk lsd 
c mk wsd 
c lk asd 
c lk lsd 
d sk wsd 
d sk asd 
d mk lsd 

Что напечатает:

a => 7, asd => 3, lk => 2, lsd => 2, mk => 1, pk => 2, sk => 2, wsd => 2, 
b => 5, asd => 1, lk => 2, lsd => 2, mk => 1, sk => 2, wsd => 2, 
c => 5, asd => 2, lk => 2, lsd => 2, mk => 1, sk => 2, wsd => 1, 
d => 3, asd => 1, lsd => 1, mk => 1, sk => 2, wsd => 1, 

Чтобы объяснить - что вам нужно хэши, которые на самом деле один из языка Perl "убийцы особенности. В приведенном выше примере у нас есть два, потому что вы хотите подсчитать две разные вещи: вхождения в первую очередь и вхождения каждого из подэлементов в этот префикс письма.

  • Так мы бежим через каждую строку DATA (вы, вероятно, хотите использовать реальный дескриптор здесь).

  • Мы используем split, чтобы превратить линию в массив, ограниченный пробелами.

  • Мы назначаем первый элемент $term и все остальное на линии в @things.

  • перечислить список @things и обновить общий счетчик в пределах определенной буквы, а также префикс/букву %count_elements_of хэш.

  • И затем мы перебираем ключи наших хешей (сортируем их) и печатаем результаты.

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

Так вместо этого, вам нужно:

#!/usr/bin/perl 
use strict; 
use warnings; 

my %count_elements_of; 
my %count_of; 
my %all_sub_elements; 

while (<DATA>) { 
    my ($term, @things) = split; 
    $count_of{$term}++; 
    foreach my $thing (@things) { 
     $count_elements_of{$term}{$thing}++; 
     $all_sub_elements{$thing}++; 
    } 
} 

foreach my $term (sort keys %count_elements_of) { 
    print "$term => $count_of{$term}, "; 
    foreach my $thing (sort keys %all_sub_elements) { 
     print "$thing => ", $count_elements_of{$term}{$thing} // 0," "; 
    } 
    print "\n"; 
} 

Это будет «создать» список всех вещей, которые, возможно, потребуется печать в %all_sub_elements, которые мы используем позже, чтобы выяснить, что к выходу. Мы используем оператор //, который является условным похожим на || (логический или), но для defined. Это не имеет большого значения в этом случае, но я думаю, что это полезное различие при работе на хешах в обычном режиме. (Поскольку хэш с нулевым значением не совпадает с хэшем с отсутствующим значением).

Который затем печатает:

a => 7, asd => 3 lk => 2 lsd => 2 mk => 1 pk => 2 sk => 2 wsd => 2 
b => 5, asd => 1 lk => 2 lsd => 2 mk => 1 pk => 0 sk => 2 wsd => 2 
c => 5, asd => 2 lk => 2 lsd => 2 mk => 1 pk => 0 sk => 2 wsd => 1 
d => 3, asd => 1 lk => 0 lsd => 1 mk => 1 pk => 0 sk => 2 wsd => 1 

Вы могли бы - в качестве альтернативы - определить массив:

my @output_order = qw (sk lk mk asd lsd wsd); 

И вместо того, чтобы использовать это для упорядочения вашей продукции, если вы предпочитаете:

foreach my $thing (@output_order) { 

и т.д.

+0

tha nks много. Работает !! Как насчет раскола, если мы имеем данные с разделителями \ t? –

+0

'split' по умолчанию означает« любые пробелы ». http://perldoc.perl.org/functions/split.html, чтобы он работал для вкладок. Но если вы хотите использовать _just_ tabs, то 'split/\ t /;' будет делать трюк. – Sobrique

+0

Теперь я хочу только цифры, а не имя вещи. Что мне нужно сделать ?? –

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