количество раз строка повторяется в файле perl - PullRequest
0 голосов
/ 06 апреля 2011

Кстати, я новичок в Perl. У меня есть Perl-скрипт, который должен подсчитать, сколько раз строка появляется в файле. Сценарий получает слово из самого файла.

Мне нужно, чтобы оно захватило первое слово в файле и затем поискало остальную часть файла, чтобы увидеть, повторяется ли оно где-нибудь еще. Если это повторяется, мне нужно вернуть количество повторений. Если это не было повторено, он может вернуть 0. Мне нужно, чтобы затем получить следующее слово в файле и проверить это снова.

Я возьму первое слово из файла, найду в файле повторы этого слова, возьму второе слово из файл, поиск в файле повторов этого слова, получение третьего слова из файла, поиск в файле повторов этого слова.

Пока у меня есть цикл while, который захватывает каждое нужное мне слово, но я не знаю, как заставить его искать повторы без сброса положения моей текущей строки. Так как мне это сделать? Любые идеи или предложения с благодарностью! Заранее спасибо!

while (<theFile>) {
    my $line1 = $_;
    my $startHere = rindex($line1, ",");
    my $theName = substr($line1, $startHere + 1, length($line1) - $startHere);
    #print "the name: ".$theName."\n";
}

Ответы [ 3 ]

4 голосов
/ 06 апреля 2011

Использовать хеш-таблицу;

my %wordcount = ();

while(my $line = <theFile>)
{
    chomp($line);
    my @words = split(' ', $line);
    foreach my $word(@words)
    {
        $wordCount{$word} += 1;
    }
}

# output
foreach my $key(keys %wordCount)
{
    print "Word: $key Repeat_Count: " . ($wordCount{$key} - 1) . "\n";
}

$wordCount{$key} - 1 в выходных данных учитывает впервые слово было замечено; Слова, которые появляются в файле только один раз, будут иметь значение 0

Если это не домашняя работа и / или вам не нужно добиваться результатов в особом поместье, которое вы описываете, это будет намного эффективнее.

Редактировать: Из вашего комментария ниже:

Каждое слово, которое я ищу, не является «первым словом», это определенное слово в строке. В основном у меня есть CSV-файл, и я перехожу к третьему значению и ищу его повторы.

Я бы все еще использовал этот подход. Что бы вы хотели сделать, это:

  • разделить на ,, поскольку это CSV-файл
  • Вытяните 3-е слово в массиве в каждой строке и сохраните слова, которые вас интересуют, в их собственной хеш-таблице
  • В конце выполните итерацию по хеш-таблице «слово для поиска» и извлеките значения из таблицы «WordCount»

Итак:

my @words = split(',', $line);
$searchTable{@words[2]} = 1;

...

foreach my $key(keys %searchTable)
{
    print "Word: $key Repeat_Count: " . ($wordCount{$key} - 1) . "\n";
}

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

1 голос
/ 19 июня 2011

Чтобы найти количество всех слов, присутствующих в файле, вы можете сделать что-то вроде:

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

my %count_of;
while (my $line = <>) { #read from file or STDIN
  foreach my $word (split /\s+/, $line) {
     $count_of{$word}++;
  }
}
print "All words and their counts: \n";
for my $word (sort keys %count_of) {
  print "'$word': $count_of{$word}\n";
}
__END__
1 голос
/ 06 апреля 2011
my $word = <theFile>
chomp($word); #`assuming word is by itself.
my $wordcount = 0;
foreach my $line (<theFile>) {
    $line =~ s/$word/$wordcount++/eg;
}
print $wordcount."\n";

Найдите флаг регулярного выражения 'e', ​​чтобы узнать, что это делает.Я не тестировал код, но что-то вроде этого должно работать.Для пояснения, флаг 'e' оценивает вторую часть регулярного выражения (подстановку) как код перед заменой, но это не так, поэтому с этим флагом вы сможете выполнить эту работу.

Теперьчто я понимаю, о чем вы просите, вышеуказанное решение не сработает.Что вы можете сделать, это использовать sysread, чтобы прочитать весь файл в буфер и запустить ту же самую подстановку после этого, но вам придется отключить первое слово вручную, или вы можете просто уменьшить значение после факта.Это потому, что файловый дескриптор sysread и обычный файловый дескриптор обрабатываются по-разному, поэтому попробуйте это:

my $word = <theFile>
chomp($word); #`assuming word is by itself.
my $wordcount = 0;
my $srline = '';
#some arbitrary very long length, longer than file
#Looping also possible.
sysread(theFile,$srline,10000000) 
$srline =~ s/$word/$wordcount++/eg;
$wordcount--; # I think that the first word will still be in here, causing issues, you should test.
print $wordcount."\n";

Теперь, учитывая, что я прочитал ваш комментарий в ответ на ваш вопрос, я не думаю, что ваш текущий алгоритмоптимально, и вы, вероятно, хотите хэш, хранящий все значения слов в файле.Это, вероятно, лучше всего сделать, используя что-то вроде следующего:

my %counts = ();
foreach my $line (<theFile>) {
    $line =~ s/(\w+)/$counts{$1}++/eg;
}
# now %counts contains key-value pair words for everything in the file.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...