2012-01-02 20 views
1

私は以下のコードを書いています。Perl。私はファイルに書き込むことはできません。ファイルは空のままです

エラーは見つかりませんでした。

しかし

say $valid $1; 

動作しません。 $有効なファイルは、プログラムが終了すると空になります。

どういうところが間違っていますか?

ありがとうございます! ^^

#!/usr/bin/perl 
use 5.012; 
use strict; 
use warnings; 
use LWP::Simple; 

open my $input, '<', 'c:\perl\015_JiraGet\addrHDP.txt' or die "Cannot read: $!\n"; 
open my $valid, '<', 'c:\perl\015_JiraGet\valid.txt' or die "Cannot read: $!\n"; 
my @totalReport; 
my $eachAddr; 
my $copyFile; 
my $copyFilePath = 'c:\perl\015_JiraGet\HADOOP XML\\'; 
my $tempFile; 
my $tempFilePath = 'c:\perl\015_JiraGet\temp.txt'; 
my $analyzed; 
my $analyzedPath = 'c:\perl\015_JiraGet\analyzed - HADOOP.txt'; 
my $undefCheck; 
my $i = 0; 
my $j = 0; 
my $title = 'temp'; 
my $dup = 0; 

while(<$input>) { chomp; push @totalReport, $_; } 
foreach(@totalReport) 
{ 
    $eachAddr = $_; 
    $undefCheck = get($eachAddr); 
    if(defined($undefCheck) == 0) { next; } 

    # Copy one XML file to 'temp.txt' and then close the file. 
    open $tempFile, '>', $tempFilePath or die "Cannot open 1: $!\n"; 
    print $tempFile get($eachAddr); 
    close $tempFile; 

    # If the entry is a duplicate, go on to the next entry 
    open $tempFile, '<', $tempFilePath or die "Cannot open 2: $!\n"; 
    ($title, $dup) = isDuplicate($tempFile, $title); 
    if($dup == 1) { close $tempFile; next; } 
    close $tempFile; 
    say ++$i . "th report!!!"; 

    # Copy one XML file to HDD. 
    if($eachAddr =~ /.*\/(.*)/) 
    { 
     say $valid $1; 
     open $copyFile, '>', $copyFilePath . $1 or die "Cannot open 3: $!\n"; 
     print $copyFile get($eachAddr); 
     close $copyFile; 
    } 

    # If the entry is NOT fixed or resolved, go on to the next entry 
    open $tempFile, '<', $tempFilePath or die "Cannot open 4: $!\n"; 
    if(isFixCloseResolve($tempFile) == 0) { close $tempFile; next; } 
    close $tempFile; 

    # Analyze one entry 
    open $tempFile, '<', $tempFilePath or die "Cannot open 5: $!\n"; 
    open $analyzed, '>>', $analyzedPath or die "Cannot open 6: $!\n"; 
    analyzeOneReport($tempFile, $analyzed); 
    close $tempFile; 
    close $analyzed; 
    say '      ' . ++$j . "th fixed & closed report!!!"; 
} 
say "$i total reports."; 
say "$j total fixed & closed reports."; 
close $input; 
close $valid; 
say "Finished!"; 

sub isDuplicate 
{ 
    my $iReport = $_[0]; 
    my $title = 'temp'; 
    my $dup = 0; 

    while(<$iReport>) 
    { 
     if ($_ =~ /.*\<title>(.*)\<\/title>/) 
     { 
      if($1 ne 'ASF JIRA') { $title = $1; if($title eq $_[1]) { $dup = 1; } last; } 
     } 
    } 
    return ($title, $dup); 
} 

# returns 1 if an entry is a Bug and Fixed and Closed 
sub isFixCloseResolve 
{ 
    my $iReport = $_[0]; 
    my $isCloseResolve = 0; 
    my $isFixed = 0; 
    while(<$iReport>) 
    { 
     if ($_ =~ /.*\<status[^>]*>(.*)\<\/status>/) { if(($1 eq 'Closed')||($1 eq 'Resolved')) { $isCloseResolve = 1;} } 
     elsif($_ =~ /.*\<resolution[^>]*>(.*)\<\/resolution>/) { if($1 eq 'Fixed') { $isFixed = 1;} } 
    } 
    return $isCloseResolve * $isFixed; 
} 

sub analyzeOneReport 
{ 
    my $iReport = $_[0]; 
    my $oReport = $_[1]; 

    while(<$iReport>) 
    { 
     chomp; 
     if ($_ =~ /.*\<title>(.*)\<\/title>/) { if($1 ne 'ASF JIRA') { say $oReport "Title : $1"; } } 
     elsif($_ =~ /.*\<assignee username="(.*)">.*\<\/assignee>/) { say $oReport "Assignee: $1"; } 
     elsif($_ =~ /.*\<reporter username="(.*)">.*\<\/reporter>/) { say $oReport "Reporter: $1"; } 
     elsif($_ =~ /.*\<type[^>]*>(.*)\<\/type>/)   { say $oReport "Type : $1"; } 
     elsif($_ =~ /.*\<priority[^>]*>(.*)\<\/priority>/) { say $oReport "Priority: $1"; } 
     elsif($_ =~ /.*\<created>(.*)\<\/created>/)  { say $oReport "Created : $1"; } 
     elsif($_ =~ /.*\<resolved>(.*)\<\/resolved>/)  { say $oReport "Resolved: $1"; } 
    } 
    say $oReport '--------------------------------------------'; 
} 

---あとがき---

はああ、私は '>' の部分に間違っていました!みんなありがとう!!

しかし、私はそれを '>'に変更しても、 'DURING PROGRAM RUNNING TIME'のファイルには何も書き込まれませんでした。

私は混乱していました...そして、私は、Perlが実際にファイルを「ファイルを閉じたとき」という内容を実際に書き込むことを発見しました。

したがって、実行時間中、4〜8時間、ファイル内に何も表示されませんでした。

ファイルが閉じられると、ファイルにデータが書き込まれます。

これが、このコードが機能していないと考えた理由の1つです。 ^^;

もう一度この問題を抱えている人はいないでしょう!あなたはこのラインから見ることができるように:)

+0

'$ copyfile-> autoflush(1)' –

答えて

5

あなただけの、読み取り機能を持つ$有効なファイルハンドルの下でファイルを開いている:

open my $valid, '<', 'c:\perl\015_JiraGet\valid.txt' or die "Cannot read: $!\n"; 

ですから、ファイルへの書き込みは何も実際にそこに行くんだろう。読み取り/書き込みにそれを変更します(あなたがそれを必要とする場合、単に使用するか、または追加+ >>の代わりに、+>以下のコードでは)次のように、あなたは、良いことがあります。ここでは

open my $valid, '+>', 'c:\perl\015_JiraGet\valid.txt' or die "Cannot read: $!\n"; 
+0

読み込みアクセスが不要なようです。私は、スクリプトがファイルをどこから読み込むのか分かりません。プレーン古い書き込み( '>')または追加( '' '')を行うべきです。 – cHao

+0

ああ、私は彼が何らかの理由で読み取りアクセスを使用している可能性があると思っていました。ええ、書き込み/追加アクセスはおそらく最善です。 – Rohaq

+0

ああ、私はその部分で間違っていた!ありがとうございました!!しかし、私はそれを '>'に変更しても、まだ 'プログラム実行中'というファイルには何も書かれていませんでした。だから私は混乱していました...そして、私は、Perlがファイルを「ファイルを閉じたときに」その内容を書き込むことを発見しました。だから、実行時間中、4〜8時間、私はファイル内に何も見ることができませんでした。これが、このコードが機能していないと考えた理由の1つです。 ^^; – JSong

12

open my $valid, '<',.... 

$validは、と表示されています。あなたは、ファイルへの書き込みをしたい場合は、代わりに書く必要があります:

open my $valid, '>',.... 

をあなたは、代わりに私はこれを確認するつもりです

open my $valid, '>>',.... 
+0

ああ、私はその部分に間違っていた!ありがとうございました!!しかし、私はそれを '>'に変更しても、まだ 'プログラム実行中'というファイルには何も書かれていませんでした。だから私は混乱していました...そして、私は、Perlがファイルを「ファイルを閉じたときに」その内容を書き込むことを発見しました。だから、実行時間中、4〜8時間、私はファイル内に何も見ることができませんでした。これが、このコードが機能していないと考えた理由の1つです。 ^^; – JSong

+1

それはあなたのためにバッファリングしています。 Perlは、データが一杯になるまでバッファにデータを保持し、バッファがいっぱいになるか、ファイルが閉じられたときにファイルにフラッシュします。バッファをファイルにすぐにフラッシュするには、次の行を使用します。 '$ | = 1; ' 。ファイルを開く前に。 – Rohaq

+0

@Rohaqありがとう!私は新しいことを学んだ! ^^ – JSong

1

を使用する既存の内容を保持し、端部のみに記述する必要がある場合まるでそれがCode Reviewに投稿されたかのようにコードします。

最初に書いているのはPerl as if it were Cです。それは一般的にそれほど悪くはありませんが、あなたが必要以上に多くの作業をしていることを意味します。代わりに、集中的なこの過度に冗長、および潜在的にメモリを使用しての


:それは入力にループするように、私は変数を排除し、それを作った方法を

my @totalReport 
... 
while(<$input>) { chomp; push @totalReport, $_; } 
foreach(@totalReport) 
{ 
    $eachAddr = $_; 
    ... 
} 
​​

お知らせ1回、2回の代わりに。また、プログラムの全長にわたってメモリ内の値を保持しません。


の代わりに、書き込み用のファイルを開く、それを閉じて、再度開き、それを:代わりに二回指定されたURLのテキストを取得する

my $tempFile; 

open $tempFile, '>', $tempFilePath or die "Cannot open 1: $!\n"; 
print $tempFile get($eachAddr); 
close $tempFile; 

open $tempFile, '<', $tempFilePath or die "Cannot open 2: $!\n"; 
open my $tempFile, '+>', $tempFilePath or die "Can't open '$tempFilePath' with mode'+>': '$!'"; 
print $tempFile get($eachAddr); 
seek $tempFile, 0, 0; 

、および奇妙に定義されたテストを使用して:

$undefCheck = get($eachAddr); 
if(defined($undefCheck) == 0) { next; } 
... 
print $tempFile get($eachAddr); 
私は autodieを使用する

open ... or die ...; 

:代わりの束の

my $text = get($addr); 
next unless defined $text; 
... 
print $tempFile $text; 

。私が指摘したいと思い

use autodie; 
... 
# will now die on error and will tell you the file it fails on. 
open my $fh, '<', $filename; 

もう一つは、die "...\n"は、エラーの場所を追加からdieを防ぐことです。あなたが行うべき唯一の時間は、デフォルトの動作が役に立たない場合です。あなたが$dupをチェックする前に$tempFileを閉じた場合


これは単純に次のようになります。

while(<$iReport>) 
{ 
    chomp; 
    if ($_ =~ /.*\<title>(.*)\<\/title>/) { if($1 ne 'ASF JIRA') { say $oReport "Title : $1"; } } 
    elsif($_ =~ /.*\<assignee username="(.*)">.*\<\/assignee>/) { say $oReport "Assignee: $1"; } 
    elsif($_ =~ /.*\<reporter username="(.*)">.*\<\/reporter>/) { say $oReport "Reporter: $1"; } 
    elsif($_ =~ /.*\<type[^>]*>(.*)\<\/type>/)   { say $oReport "Type : $1"; } 
    elsif($_ =~ /.*\<priority[^>]*>(.*)\<\/priority>/) { say $oReport "Priority: $1"; } 
    elsif($_ =~ /.*\<created>(.*)\<\/created>/)  { say $oReport "Created : $1"; } 
    elsif($_ =~ /.*\<resolved>(.*)\<\/resolved>/)  { say $oReport "Resolved: $1"; } 
} 
:代わりにこのコードの繰り返しブロックの

if($dup == 1) { close $tempFile; next; } 
close $tempFile; 
close $tempFile; 
next if $dup; 
use List::Util qw'max'; 
my @simple_tags = qw'title type priority created resolved'; 
my $simple_tags_length = max map length, @simple_tags, qw'assignee reporter'; 
my $simple_tags = join '|', @simple_tags; 
... 
while(<$iReport>){ 
    my($tag,$contents); 
    if(($tag,$contents) = /<($simple_tags)[^>]*>(.*?)<\/\g{1}>/){ 
    }elsif(($tag,$contents) = /<(assignee|reporter) username="(.*?)">.*?<\/\g{1}>/){ 
    }else{ next } 
    printf $oReport "%-${simple_tags_length}s: %s\n", ucfirst($tag), $contents; 
} 

このコードは任意の短い、または明確ではありませんが、と比較する別のタグを追加する非常に簡単だろう。だから、実際にはの方がよく、より反復的ではありません。です。
$_ =~ /...//.../と書かれています。


おそらくコードの最悪の部分は、あなたのほとんどすべての変数を定義するということです。

my @totalReport; 
my $eachAddr; 
my $copyFile; 
my $copyFilePath = 'c:\perl\015_JiraGet\HADOOP XML\\'; 
my $tempFile; 
my $tempFilePath = 'c:\perl\015_JiraGet\temp.txt'; 
my $analyzed; 
my $analyzedPath = 'c:\perl\015_JiraGet\analyzed - HADOOP.txt'; 
my $undefCheck; 
my $i = 0; 
my $j = 0; 
my $title = 'temp'; 
my $dup = 0; 

これは実際にグローバル変数を使用していることを意味します。これらのうちのいくつかは定義する必要があるように見えますが、その中には定義されていないものもあります。変数は、必要な時点で、または少なくとも必要なブロックの先頭に定義する必要があります。

+0

おかげさまで、ありがとうございました。既に推測しているように、私はCを数年間使っていて、わずか4ヶ月前にPerlを使い始めました。あなたのコメントは私を大いに助けます。本当にありがとう、新年あけましておめでとう! ^^ – JSong

+0

@ user1125721私は、私が過度に批判的になるかもしれないと心配しました。私は少なくともあなたがそうは思わないとうれしいです。 –

関連する問題