Так как это обзор кода, давайте пойдем один за другим:
#!/use/bin/perl
Эта линия Шебанга, скорее всего, опечатка. Вероятно, должно быть
#!/usr/bin/perl
или что-то еще which perl
возвращается в вашу систему.
use strict;
use warnings;
Хорошо.
open (FILE, "/home/user/Desktop/infile.phy") || die "cant open file\n";
Нет необходимости в пакетных глобальных файловых дескрипторах, когда вы можете использовать лексические файловые дескрипторы. Форма с тремя аргументами open
предпочтительнее в наши дни. Также в сообщении об ошибке должен быть указан файл, который вы не смогли открыть:
my $filename = '/home/user/Desktop/infile.phy';
open my $input, '<', $filename
or die "Cannot open '$filename' for reading: $!";
my @body = <FILE>;
Вы записываете файл в массив. Это совершенно не нужно в этом случае.
my $count = 0;
my $string = '';
Объявите и инициализируйте (при необходимости) любые переменные в наименьшей возможной области действия.
my $count;
Переменная $string
больше нигде в вашем коде не используется.
foreach $_(@body){
Это глупо. for
использует $ _, если переменная цикла не указана. Проще не усложнять ситуацию, если вместо этого указать переменную лексического цикла.
for my $line ( @body ) {
Тем не менее, я не думаю, что вы должны украсть файл.
if ($_ =~ m/[X]/){
Это приводит к успешному совпадению, если строка содержит X. Таким образом, оно эквивалентно /X/
. Тем не менее, это не скажет вам слово, которое содержит «X». Для этого вам нужно решить, что такое слово, и сопоставить его на уровне слов.
Учитывая все это, рассмотрим следующий сценарий. Я сделал упрощающее предположение относительно того, что я считаю словом. Вы должны быть в состоянии опираться на это, чтобы удовлетворить все требования:
#!/usr/bin/perl
use strict;
use warnings;
my $filename = "$ENV{TEMP}/test.txt";
open my $input, '<', $filename
or die "Cannot open '$filename' for reading: $!";
my $count;
while ( my $line = <$input> ) {
my @words = grep { /X/ } split /\b/, $line;
$count += @words;
print join(', ', @words), "\n";
}
print "$count\n";
__END__
ОБНОВЛЕНИЕ: Если вам не нужно искать слова в каждой строке, содержащие один или несколько символов X, цикл while будет упрощен:
while ( <$input> ) {
$count += (my @matches = /(X)/g );
print if @matches;
}
с использованием $ _. Это, однако, вероятно, неэффективно (учитывая, что мы сохраняем каждый соответствующий X символ). В этом случае tr
работает лучше всего:
my ($count, $n);
$n = tr/X// and $count += $n and print while <$input>;