Как мне распечатать определенный символ в файле после прочтения файла?

StackOverflow https://stackoverflow.com/questions/969999

Вопрос

Я читаю файл, используя Perl-скрипт.Этот файл состоит из строк с разными символами, и я должен идентифицировать строки, содержащие символ «X».Я хочу знать, как мне следует (1) распечатать эту строку (содержащий 'X'), а также (2) записать эту строку в другой файл (3) подсчитать количество символов «X» во всем файле.Сценарий ниже снова печатает весь файл.Какие-либо предложения?

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

open (FILE, "/home/user/Desktop/infile.phy") || die "cant open file\n";
my @body = <FILE>;
close (FILE);
my $count= 0;
my $string = '';
foreach $_(@body){
    if ($_ =~ m/[X]/){
        print "$_";
        $count++;
        print $count;
    }
    else {
        print ;
    }
}
exit;
Это было полезно?

Решение

Поскольку это проверка кода, давайте пойдем по порядку:

#!/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>;

Другие советы

Вы печатаете $_ в обеих ветвях вашего предложения if.Избавьтесь от ветки else.

Предполагая, что «строка» в вашем вопросе равна «строке»:

use strict;
use warnings;

@ARGV=qw(/home/user/Desktop/infile.phy);

my $count = 0;
open my $outfile, '>', 'outfile' or die $!;
while (<>) {
  my $cnt = tr/X/X/;
  if ($cnt) {
    print;
    print $outfile $_;
  }
  $count += $cnt;
}

close $outfile or die $!;

print $count;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top