2009-06-09 4 views
0

나는 펄 스크립트를 사용하여 파일을 읽는다. 이 파일은 다른 문자가있는 문자열로 구성되어 있으며 문자 '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; 
+1

이 숙제가 있습니까? –

+1

나는 똑같은 생각을하고 있었지만 입문 문구의 샘플 문제 일 수도 있습니다. – inkedmn

+1

어떤 시점에서 '다른 파일'을 열고 파일에 쓰기를해야합니다. 또한 '열린'형태의 사용을 피하십시오. 일반 $ 변수와 함께 사용할 파일 핸들을 반환하는 양식을 사용하십시오. open ($ fh, "filename"); 또는 변종 중 하나. –

답변

4

, 하나 하나의 가자 : 귀하의 질문에 "문자열을"가정

+0

모든 검토 의견에 동의합니다. 그러나 3 번 질문은 "전체 파일에서 'X'문자의 수를 계산합니다."라고 묻습니다. 대신 솔루션에서 'X'문자가 포함 된 단어 수 (문자열은 "문자열"정의에 따라 다름)를 계산합니다. – user55400

+0

@blixtor : 캐치를 가져 주셔서 감사합니다. 물론 각 단어에는 여러 개의 X 문자가 포함될 수 있습니다. 사실, 나는 OP가 줄을 단어들로 나누는 것에 신경을 쓰지 않는다는 것을 깨닫는다. –

+0

열린 3-arg 형식은 때로는 유용하고 때때로 그렇지 않다. 2-arg 오픈은 항상 안전하게 사용하기 쉽고 오픈 플러그 또는 -C 스위치에서 기본 IO 레이어를 가져 오는 기능이 필요합니다. 2-arg가 열리는 것을 비판한다면 적어도 "새로운 방법"이 아니라 "언젠가 가변적 인 파일 이름을 안전하지 않게 사용할 수 있기 때문에"라고 말하십시오. – ysth

1

당신은 당신의 경우 절의 두 지점에서 $_를 인쇄 할 수 있습니다. else 브랜치를 제거하십시오. 라인이 가장 가능성이 오타입니다 오두막 그

#!/use/bin/perl 

:이 코드 리뷰이기 때문에

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; 
+0

신입 사원에게는 '인쇄'가 명확하지 않을 수 있습니다. '$ _'을 출력하지만, 그렇게됩니다. –

+0

. 나는 좀 더 장황 할 수 있었다. 죄송합니다. – innaM

0

는 "선"과 동일 . 아마도

#!/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) { 

그러나 나는 파일을 긁어 모을 필요가 없다고 생각합니다. 라인이 그래서 X를 포함하는 경우 성공적인 경기 결과

 if ($_ =~ m/[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__ 

UPDATE : 하나 개 이상의 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>; 
관련 문제