2

したがって、次のコードで私がやろうとしているのは、文字列をプッシュすることです。たとえば、「この文字列」をハッシュの各キーの末尾にプッシュします。私はこれを行う方法に完全に困惑しています。これが私のコードです:

use warnings;
use strict;
use File::Find;

my @name;
my $filename;
my $line;
my @severity = ();
my @files;
my @info = ();
my $key;
my %hoa;
my $xmlfile;
my $comment;
my @comments;

open( OUTPUT, "> $ARGV[0]" );
my $dir = 'c:/programs/TEST/Test';

while ( defined( $input = glob( $dir . "\\*.txt" ) ) ) {
    open( INPUT, "< $input" );

    while (<INPUT>) {
        chomp;

        if (/File/) {
            my @line = split /:/;
            $key = $line[1];
            push @{ $hoa{$key} }, "Filename\n";
        }

        if ( /XML/ ... /File/ ) {
            $xmlfile = $1;
            push @{ $hoa{$key} }, "XML file is $xmlfile\n";

        }
        if (/Important/) {
            push @{ $hoa{$key} }, "Severity is $_\n";
        }
        if (/^\D/) {
            next if /Important/;
            push @{ $hoa{$key} }, "Given comment is $_\n";
        }
        push @{ $hoa{$key} }, "this string\n";
    }

}

foreach my $k ( keys %hoa ) {
    my @list = @{ $hoa{$k} };
    foreach my $l (@list) {
        print OUTPUT $l, "\n";
    }
}

}
close INPUT;
close OUTPUT;

「この文字列」がある場所は、その文字列を配列の最後にプッシュしようとしていた場所です。しかし、最終的には、「この文字列」を 3 回出力することになり、すべてのキーの最後に表示されることはありませんでした。while()ループの外に出そうとしたら、$keyの値が初期化されていないとのことでした。それでお願いします、何か助けて?また、私が尋ねていることについて明確にする必要がある場合は、お知らせください。ありがとうございました!

4

5 に答える 5

3

問題はありませんが、このコードには非常に多くの問題があり、どこから始めればよいかわかりません...

まず、「初期化ブロック」(my $something; my @somethingsこのスクリプトの先頭にあるこれらすべての行) は Perl では必要ありません。実際、これは単なる「冗長」ではなく、混乱を招きます。新しい変数に遭遇するたびに、型を確認するためだけにフォーカスを前後に移動する必要がありました。さらに、このすべての$inputvar でもまだローカルとして宣言されていません。コメントに含まれていないか、指定されたコードに抜けがあります。

第二に、なぜ File::Find を使用する意図を宣言するのですか (良い) - しかし、まったく使用しないのですか? このすべてのwhile(glob) { while(<FH>) { ... } }ルーチンを大幅に簡素化できます。

第三に、読み取った行が /File/ と一致する場合にのみ何かを割り当てる理由がわかりません$keyが、他のすべての場合ではその値をキーとして使用します。これは、セクションで編成されたファイルを読み取ろうとする試みですか? 次に、丸呑み/分割するか、変数をローカライズすることにより、もう少し簡単に行うことができ$/ます...

とにかく、ポイントは、スキャンされたファイルの最初の行が によって一致しない/File/場合、前の (つまり、前のファイルから!) 値が使用されるということです。これが意図されているかどうかはよくわかりません。そして、最初のファイルの最初の行が一致しない/File/場合、空の文字列がキーとして使用されます - これもバグのような匂いがします...

あなたの仕事をもっと詳しく説明していただけますか?おそらく、いくつかのテスト入出力結果を提供してください...短いタスクを進めて、進行中のコードを整理するのは素晴らしいことです。

于 2012-07-20T13:47:51.717 に答える
3

あなたのプログラムは考えが浅く、多くの優れた実践規則に違反しています。それらをすべて列挙するのではなく、より良い構造を持つ同等のプログラムを次に示します。

すべてifステートメントがテストされ、場合によっては実行されることをご存知ですか? おそらくあなたは利用する必要がありelsifますか?

使用時に $key が未定義である可能性は別として、どの正規表現にもキャプチャがないため、 which が定義されないこと$xmlfileも設定しています。$1

あなたのコードからあなたが何をしようとしているのかを知ることは不可能です。そのため、あなたの出力、入力を示し、一方を他方から導き出す方法を教えていただければ、私たちはあなたを助けることができます.

use strict;
use warnings;

use File::Find;

my ($outfile) = @ARGV;

my $dir = 'c:/programs/TEST/Test';

my %hoa;
my $key;

while (my $input = glob "$dir/*.txt") {

  open my $in, '<', $input or die $!;

  while (<$in>) {

    chomp;

    if (/File/) {
      my $key = (split /:/)[1];
      push @{ $hoa{$key} }, "Filename\n";
    }

    if (/XML/ ... /File/) {
      my $xmlfile = $1;
      push @{ $hoa{$key} }, "XML file is $xmlfile\n";
    }

    if (/Important/) {
      push @{ $hoa{$key} }, "Severity is $_\n";
    }

    if (/^\D/) {
      next if /Important/;
      push @{ $hoa{$key} }, "Given comment is $_\n";
    }

    push @{ $hoa{$key} }, "this string\n";
  }

  close $in;
}

open my $out, '>', $outfile or die $!;

foreach my $k (keys %hoa) {
  foreach my $l (@{ $hoa{$k} }) {
    print $out $l, "\n";
  }
}

close $out;
于 2012-07-20T14:47:20.227 に答える
1

あなたのコードに基づいて、 $key が設定されている行がループのたびに呼び出されず、他の if ステートメントをトリガーしないと思われます。

これにより、「この文字列」が配列の末尾に追加されます。配列の最後に「この文字列」を 3 つ取得していることに基づいて、2 行が if (/FILE/) または他の if ステートメントを通過していないと思われます。これにより、$key 値は同じままになり、最後に、設定されたときの $key の最後の値を使用して、「この文字列」を配列に追加します。

于 2012-07-20T13:47:26.037 に答える
0

map私が理解しているように、キーを変更するコマンドでハッシュをトラバースします。例:

編集map:コマンドを同じハッシュに割り当てることができることに気付いたので、編集しました。新しいものを作成する必要はありません。

#!/usr/bin/perl

use warnings;
use strict;
use Data::Dumper;

my %hash = qw|
    key1    value1
    key2    value2
    key3    value3
|;

my %hash = map { $_ . "this string" => $hash{ $_ } } keys %hash;

print Dump \%hash;

次のように実行します。

perl script.pl

次の出力で:

$VAR1 = {
          'key3this string' => 'value3',
          'key2this string' => 'value2',
          'key1this string' => 'value1'
        };
于 2012-07-20T13:41:52.433 に答える