2011-01-03 20 views
-1

どのように私はperlで複数のファイルを読み込み、ハッシュでそれらを保存できますか?複数のファイルを読む?

ありがとうございました。

+1

を何がうまくいかない? –

+0

どのようにファイルを指定していますか?名前のリストまたはglob(ワイルドカード) – justintime

答えて

13
my %data; 
my @FILES = @ARGV; 
# or maybe @FILES = glob("some/directory/*.ext"); 

これはPerlであるため、さまざまな方法があります。

彼らは、コマンドライン引数なら、あなたはそれらの上にこのようなすべての反復処理することができ、たとえば、すべてのファイルが @ARGVであると仮定すると、
# 1. Open and load each file  
foreach my $file (@FILES) { 
    local $/ = undef; 
    open my $fh, '<', $file; 
    $data{$file} = <$fh>; 
} 

# 1b. Using map 
%data = map { 
    local $/=undef; 
    open my $fh, '<', $file; 
    my $data = <$fh>; 
    $_ => $data 
} @FILES; 

# 2. Leverage your operating system 
foreach my $file (@FILES) { 
    $data{$file} = qx(/bin/cat "$file"); 
} 

# 3. Use a module 
use File::Slurp; 
foreach my $file (@FILES) { 
    $data{$file} = File::Slurp::slurp($file); 
} 

# 3b, using map 
use File::Slurp; 
%data = map { $_ => File::Slurp::slurp($_) } @FILES; 
+0

+1最初の2つのオプションについて - これらのファイルを閉じるのはどうですか? (私はこれが厳密に要求されていないことを知っています)。 Perlは自動的にファイルを閉じるRubyのFile.open(){}のようなものを持っていますか? – nimrodm

+2

範囲外になると字句のファイルハンドル(my $、my $ fhで宣言したファイルハンドル)が自動的に閉じるようになりました。 – Hugmeir

+0

これはいくつかのセクシーなperlです。特に2番目の解決策が好きです.3番目はプラットフォーム依存ではなく、私の好きなものです(エレガントに見えます:)) –

4

このperlfaqエントリを参照してください:コードの繰り返し処理は、コマンドラインとして渡され、この場合には、ファイル名のリストの上に

my %hash = (
    filename => $file_content, 
    # ... 
); 
1
my %data; 
foreach my $fn (@ARGV) { 
    open (my $IN, $fn) or die "couldn't open $fn: $!"; 
    $data{$fn} = join "", <$IN>; 
    close $fn; 
} 

foreach my $key (keys %data) { 
    print "File $key:\n$data{$key}\n\n\n"; 
} 

How can I read in an entire file all at once?

ハッシュは次のように作成することができます@ARGVの引数。それぞれのファイル名に対して、ファイルハンドルを開き、ファイルの各行を配列の要素としてロードする配列コンテキストでファイルハンドルを読み込みます。この場合、私たちは無名配列に読み込み、joinに渡されます。結合は配列の要素を結合します。この場合は空の文字列をセパレータとして使用します。その結果、ファイル内容全体を含む1つの文字列が、ファイル名をキーとしてハッシュに格納されます。 2番目のループは結果を出力します。

大きなファイルの場合、これは自分自身を高速メモリから実行するための良い方法です。ストリーミングモードでデータを処理する方法について考えてみましょう。

+0

なぜwhile(<>)を使わないのですか? –

+0

@Nathan Fellman - スタイルの問題、私は思います。 @ARGVにあるファイル名に頼るのではなく、関数に直接変換できるので、私はこのようにしました。また、そのイディオムで現在読み込まれているファイルの名前を取得する方法を調べる気がしなかった。 –

0

:あなたがしようとしているものの例を与えることができ

@array =(); 
while (<>) { 
    push @array, $_; 
    # or any other manipulation on the lines 
    # for instance extracting a key and value from 
    # the line and putting them into a hash 
} 
関連する問題