3

ファイルハンドルを引数として取るサブルーチンがあります。コマンド ラインで指定されたファイル パスからファイルハンドルを作成するにはどうすればよいですか? 私はこのファイルを自分で処理したくありません。ファイルから解析されたすべてのデータを含むハッシュの配列を返すこの別のサブルーチンに渡したいだけです。

私が使用しているコマンドライン入力は次のようになります。

$ ./getfile.pl /path/to/some/file.csv

私が呼び出しているサブルーチンの始まりは次のようになります。

sub parse {
    my $handle = shift;
    my @data   = <$handle>;
    while (my $line = shift(@data)) {
      # do stuff
    }
}
4

4 に答える 4

16

コマンド ライン引数は、事前定義された@ARGV配列で使用できます。そこからファイル名を取得し、それを使用openしてファイルハンドルを開くことができます。ファイルへの読み取り専用アクセスが必要な場合は、次のようにします。

my $file = shift @ARGV;
open(my $fh, '<', $file) or die "Can't read file '$file' [$!]\n";
parse($fh);

or die...は呼び出しopenが成功したかどうかをチェックし、失敗した場合はエラー メッセージを表示して終了することに注意してください。組み込み変数$!には、呼び出しが成功しなかった理由を示す失敗時の (OS 依存の) エラー メッセージが含まれます。例: 「許可が拒否されました。」

于 2008-10-09T21:39:00.310 に答える
5

parse(*ARGV)が最も簡単な解決策です。説明は少し長くなりますが、Perl を効果的に使用する方法を学ぶ上で重要な部分は、Perl を学ぶことです。

null ファイルハンドル ( <>) を使用すると、実際にARGVは特別なセマンティクスを持つ魔法のファイルハンドルから読み取ります: で指定されたすべてのファイルから読み取り@ARGVます。STDIN@ARGV

からperldoc perlop:

null ファイルハンドル<>は特別です: sed と awk の動作をエミュレートするために使用できます。からの入力<>は、標準入力から、またはコマンド ラインにリストされた各ファイルから取得されます。これがどのように機能するかです: 初めて<>が評価され、@ARGV配列がチェックされ、空の場合$ARGV[0]は に設定され"-"、開かれると標準入力が得られます。次に、@ARGV配列はファイル名のリストとして処理されます。ループ

while (<>) {
    ...                     # code for each line
}

次の Perl ライクな擬似コードと同等です。

unshift(@ARGV, '-') unless @ARGV;
while ($ARGV = shift) {
    open(ARGV, $ARGV);
    while (<ARGV>) {
        ...         # code for each line
    }
}

ただし、言うのはそれほど面倒ではなく、実際に機能します。実際に@ARGV配列をシフトし、現在のファイル名を $ARGV変数に入れます。また、ARGV内部でファイルハンドルを使用します。これは魔法のように<>の同義語です。<ARGV>(上記の疑似コードは<ARGV>、非魔法として扱われるため機能しません。)

ループで使用<>する必要はありません。最初の空でないファイルから 1 行を読み取り、一度にすべて丸呑みし、通常のファイルハンドルであるかのように渡すことができます。whilemy $data = <>my @data = <>;*ARGV

于 2008-10-10T01:42:53.997 に答える
1

これが -n スイッチの目的です。

parse メソッドを使用して、次のようにします。

#!/usr/bin/perl -n

#do stuff

各行は $_ に格納されます。だからあなたは走る

./getfile.pl /path/to.csv

そして、それはこれを行います。

これらの詳細については、こちらこちらを参照してください。私も -p が好きで、-a と -F の組み合わせが非常に便利であることがわかりました。

また、追加の処理を行いたい場合は、BEGIN ブロックと end ブロックを追加します。

#!/usr/bin/perl -n

BEGIN {
  my $accumulator;
}

# do stuff

END {
  print process_total($accumulator);
}

または何でも。これは非常に便利です。

于 2008-10-10T20:14:57.017 に答える
-1

何か不足していますか、それとも open() 呼び出しを探しているだけですか?

open($fh, "<$ARGV[0]") or die "couldn't open $ARGV[0]: $!";
do_something_with_fh($fh);
close($fh);
于 2008-10-09T21:36:16.837 に答える