2

perlで次のコマンドを使用しようとしていますが、エラーが発生します

system("zcat myfile.gz | wc > abc.txt");

しかし、これを実行すると、予期しないトークン `|' の近くでエラー構文エラーが発生します。

削除し>abc.txtてもエラーが発生します。

システムコマンドでパイプを使用できますか?

エラーの詳細は次のとおりです。

sh: -c: line 1: syntax error near unexpected token `|'
sh: -c: line 1: ` | wc '
4

3 に答える 3

5

次回は、デモ プログラムをテストして、実際に動作することを確認してください。あなたは実際にもっと近いものを走らせました

while (my $file_name = <>) {
   system("zcat $file_name | wc > abc.txt");
}

その中には、次の 2 つのエラーがあります。

  • 末尾の改行を削除しなかったため、シェルは実行しようとしていました

    zcat def.gz
     | wc >abc.txt
    

    それ以外の

    zcat def.gz | wc >abc.txt
    
  • コマンドに埋め込む前に、ファイル名をシェルリテラルに変換しませんでした。

    ファイル名にスペースが含まれているとどうなるか考えてみてください。あなたは実行するでしょう

    zcat def ghi.gz | wc >abc.txt
    

    それ以外の

    zcat 'def ghi.gz' | wc >abc.txt
    

解決:

use String::ShellQuote qw( shell_quote );

while (my $file_name = <>) {
   chomp($file_name);
   system("zcat -- ".shell_quote($file_name)." | wc > abc.txt");
}
于 2013-02-01T13:05:08.483 に答える
1

期待どおりに動作しています:

perl -lne 'system("cat *.java|wc");'

ファイル名がおかしいかもしれません。

次のようにシェルの補間を確認できます。

my @file = `ls -1 myfile*.gz`;chomp(@files);
print join("\n",@files);

バックティック、|、qx で開くなど、perl で実行できる方法は他にもあります。

ファイル名に問題がある場合は、自分でファイル名を取得し、特定の方法でシステムを呼び出してシェルの実行を回避できます: http://docstore.mik.ua/orelly/perl/cookbook/ch19_07.htm

スカラー引数が 1 つしかない場合は、シェルのメタ文字について引数がチェックされ、存在する場合は、解析のために引数全体がシステムのコマンド シェルに渡されます (Unix プラットフォームでは /bin/sh -c ですが、環境によって異なります)。他のプラットフォーム)。引数にシェルのメタ文字がない場合、それは単語に分割され、より効率的な execvp に直接渡されます。

于 2013-02-01T11:20:21.237 に答える