문제

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";

어휘 파일 핸들을 사용할 수있을 때 패키지 글로벌 파일 핸들이 필요하지 않습니다. 3 차례 형태 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-clause의 두 가지 모두에서. 다른 지점을 제거하십시오.

질문에서 "문자열"이 "줄"과 같다고 가정하면 :

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