Как l oop через файл и подсчитать указанные c значения в perl? - PullRequest
0 голосов
/ 27 апреля 2020

Допустим, у меня есть файл со строками, такими как:

*some numbers* :00: *somenumbers*
*somenumbers* :21: *somenumbers*

И для каждого числа между :: Мне нужно подсчитать, сколько раз оно повторяется в файле?

while (<>){     
    chomp($_);
    my ($nebitno,$bitno,$opetnebitno) = split /:/, $_;
    $count{$bitno}++;
}
foreach $bitno(sort keys %count){
    print $bitno," ",$count{bitno}, "\n";
}

Ответы [ 2 ]

2 голосов
/ 27 апреля 2020

То, что вы создали, было не плохим кодом - оно выполняло работу для одного файла за раз. Приспособление кода, показанного в вопросе, для обработки нескольких файлов, сброса счетчиков после каждого файла:

#!/usr/bin/perl

use strict;
use warnings;

my %count = ();

while (<>) {     
    my ($nebitno, $bitno, $opetnebitno) = split /:/, $_;
    $count{$bitno}++;
}
continue
{
    if (eof) {
        print "$ARGV:\n";
        foreach $bitno (sort keys %count) {
            print "$bitno $count{bitno}\n";
        }
        %count = ();
    }
}

Ключом здесь является блок continue и тест if (eof). Вы можете использовать close $ARGV в блоке продолжения для сброса $. (номер строки) при изменении файла; это обычное использование для этого. Этот вид резюме для файла - другое использование. Другие изменения космети c. Вам не нужно разбивать строку (хотя в этом случае нет особого вреда); Я печатаю целые строки, а не использую разделенные запятыми списки (это хорошо работает здесь и очень часто). Я использую еще несколько пробелов. Я оставил его в формате 1TBS для блоков кода, хотя сам этим не пользуюсь (я использую Allman).

В моем черновом решении использовался практически такой же код печати, как показано выше, но основной while l oop немного отличался:

#!/usr/bin/env perl

use strict;
use warnings;

my %counts = ();

while (<>)
{
    $counts{$1}++ if (m/.*:(\d+):/);
}
continue
{
    if (eof)
    {
        print "$ARGV:\n";
        foreach my $number (sort { $a <=> $b } keys %counts)
        {
            print ":$number: $counts{$number}\n"
        }
        %counts = ();
    }
}

Единственное преимущество по сравнению с тем, что вы использовали, заключается в том, что если какая-то строка не содержит числа, заключенного в двоеточие, она игнорирует строку, тогда как ваша не делает ' не считаю такую ​​возможность. Я не уверен, что код сравнения в sort необходим - он гарантирует, что сравнения будут нумерацией c. Если числа имеют одинаковую длину и дополняются нулями слева при необходимости, проблем нет. Если они более широко отформатированы, сравнение «принудительного числа» c может иметь значение.

Помните: это Perl, так что TMTOWDTI (есть больше, чем один способ сделать это). Кто-то другой может предложить более простое решение.

0 голосов
/ 27 апреля 2020

Требуемый вывод может быть достигнут с помощью следующего фрагмента кода

  • ищите шаблон :\d+: в строке
  • с шагом ha sh %count для di git
  • вывод результата на консоль
use strict;
use warnings;
use feature 'say';

my %count;

/:(\d+):/ && $count{$1}++ for <>;

say "$_ = $count{$_}" for sort keys %count;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...