0

約6000文のテキストファイルがあり、それぞれが独自の行にあります。WindowsコマンドプロンプトでStanfordParserを使用して、文を解析したいと思います。ただし、一度に1つの文をパーサーに送信する必要があります(文が別のファイルの文と整列しているため)。

Perlラッパーを次のように記述します。入力ファイルから一時ファイルに1つの文を書き込み、一時ファイルをパーサーに送信し、1つの文を解析し、解析した出力を出力ファイルに書き込み、出力ファイルを自分に書き込みます。大きな出力ファイル、ParsedOutput.txt。

これはおそらく非常に基本的なことですが、私は行き詰まっています。どんな助けやガイダンスも本当にありがたいです。

ありがとうございました!:)

編集:これは私がこれまでに試したことです:

open (ENGDATA, "<1tot1660.txt");
open (ENGDATAOUT, ">temp.txt");
while (<ENGDATA>)
{
my $line = $_;
chomp $line;    
while ($line)
    {
    my @OneLine = $line;
    print ENGDATAOUT "$OneLine[0]\n";
    shift(@OneLine);
    }
}

私が考えていたのは、各行を配列の要素として持ち、0番目の要素を一時出力ファイルに書き込んでから、最初の要素を削除することです(誤って再度使用されないようにするため)。私は基本的にプログラム全体に固執していますが、今のところ、一時出力ファイルに(一度に)1行を書き込むときです。

編集!(もう一度..ありがとう、TLPとamon!:))これは私が最終的にしたことです:

open (ENGDATA, "<Testing10.txt");
open (ENGDATAOUT, ">TempOut.txt");
open (PARSEDOUT, ">ParsedOutput.txt");

while (<ENGDATA>)    
{
    my $line = $_;
    chomp $line;
    my $inputfilename = $line;
    print ENGDATAOUT "$line\n";

    my $parsecommand = qx(java -mx150m -cp "*;" edu.stanford.nlp.parser.lexparser.LexicalizedParser -outputFormat "penn,typedDependencies" edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz $inputfilename);

    print PARSEDOUT "$parsecommand\n";
}

入力内のすべての単語でこのエラーが発生します。

解析ファイル:superior edu.stanford.nlp.process.DocumentPreprocessor:パスsuperiorを開くことができませんでした解析ファイル:superior[0文]。

これはどういうことですか?誰か知っていますか、助けてもらえますか?ありがとう!

4

2 に答える 2

1

なんと、シェルスクリプト版。

while read -r; do
    printf '%s\n' "$REPLY" >tmp
    parser -input tmp -output tmp2
    cat tmp2
done <input >output
rm tmp tmp2

パーサーが標準入力から読み取り、結果を標準出力に書き込むことができる場合、これは大幅に簡素化できます。Linux では、ファイル名の引数が必要な場合に/dev/fd/0使用できます。/dev/fd/1

printf '%s\n' "$REPLY" |
parser -input /dev/fd/0 -output /dev/fd/1

一時ファイルを完全に削除します。

于 2012-08-18T19:48:18.147 に答える
0

Ok。1tot1160.txtあなたのコードはファイルをにコピーしてtemp.txtいるようで、途中で非常に興味深い構文が導入されています;-)

私は次のようにします:

  1. すべてのファイル名を 1 か所で宣言します。

    #!/usr/bin/perl
    use strict; use warnings;
    my $BigInFile     = ...;
    my $BigOutFile    = ...;
    my $ParserInFile  = ...;
    my $ParserOutFile = ...;
    
  2. 大きなファイルを開き、入力のループを開始します。

    open my $BigIn,  '<', $BigInFile  or die "Cant open $BigInFile";
    open my $BigOut, '>', $BigOutFile or die "Cant open $BigOutFile";
    while (defined(my $line = <$BigIn>)) {
        print $BigOut doStanford($line);
    }
    

    Big Input File の各行を、$lineそれが定義されている間 (読み取り: EOF がない間) に入れます。次に、既に終了改行があると仮定して、サブルーチンの出力をdoStanfordビッグ出力ファイルに出力します。そうでない場合は、追加するコードを自由に記述してください。

  3. サブルーチンを書きdoStanfordます。行を取得し、一時ファイルに書き込み、プログラムを呼び出し、他の一時ファイルを読み取り、内容を返します。

    sub doStanford {
        my ($line) = @_; # unpack arguments
    
        # open the firstfile:
        open my $StanfordIn, '>', $ParserInFile
          or die "Couldn't open $ParserInFile";
        print $StanfordIn $line; # already has newline
        close $StanfordIn;
    
        # do the call to the parser. I don't know the interface
        # so I assume it is "parser --in INFILE --out OUTFILE"
        my $returnValue = system("parser",
          "--in", $ParserInFile,
          "--out", $ParserOutFile);
        if ($returnValue != 0) {
            # an error occured
            die "The Parser exited with return value $?: $!.\n";
        }
    
        # read in the other file, and return:
        open my $StanfordOut, '<', $ParserOutFile
          or die "Couldn't open $ParserOutFile";
        my $parsed = <$StanfordOut>; # we only want the first line
        return $parsed;
        # implicit close $StanfordOut
    }
    

;-) ここにはいくつかのタイプミスがあるかもしれませんので、自分で書いたほうがいいです.

system良いスタイルの呼び出しのためにいくつかのエラー処理を行いました。終了値 0 は成功を示し、0 以外の終了値 (特に -1) は何らかのエラーまたは異常終了を示します。

パーサーがファイルではなく STDOUT に出力できる場合は、内部でコマンドを実行できますqx{}

my $parsed = qx{parser --in INFILE};

そうすれば、エラー処理を行うことはできませんが、余分なファイルは必要ありません。

呼び出し内でsystem、引数をリストに分割します。文字列を 1 つだけ指定すると、コマンド ラインはそれをすべてのスペースで分割します。パス名にスペースも含まれている場合は望ましくありません。私がこれをした方法で、彼らは安全です。

これにモジュールを使用できる場合は、モジュールを使用します。より安全で簡単です。

編集

  • の戻り値systemは、実際には呼び出されたコマンドの終了ステータスではありません。コマンドが成功した場合の戻り値は 0 で、エラーの場合は true です。終了ステータスは式の値です$? >> 8$!理由に設定することができます。
于 2012-08-18T12:38:27.120 に答える