私はcsvファイルを持っていて、Perlを使用してファイル内の一致する列に基づいてファイルをより小さなファイルに分割したいと思います。私はLinux Rhel6で作業しています。
例:
fruit1, fruit2,pricerate,quantity
orange, apple, 3,9
apple,lemon,8,1
orange, apple,3,8
pineapple,papaya,9,19
orange,apple,3,7
pineapple,papaya,9,10
出力は次のようになります。
ファイル1:
fruit1,fruit2,pricerate,quantity
orange,apple, 3,9
orange,apple,3,8
orange,apple,3,7
ファイル2:
fruit1,fruit2,pricerate,quantity
pineapple,papaya,9,19
pineapple,papaya,9,10
一致しない項目は別のファイルに移動されます。ファイル3を教えてください。
答え1
この問題を解決する1つの方法は次のとおりです。
- 入力ファイルを開く
- 入力ファイルの最初の行(タイトル)を保存します。
入力ファイルのヘッダーの後の各行に対して、次の操作を行います。
- 最初の2列を読む
- 一致させたいフィールドの出力ファイルをまだ開いていない場合は、新しい出力ファイルを開き、そのファイルハンドルをハッシュに保存します。また、新しい出力ファイルにヘッダー行を書き込みます。
- ファイルハンドルハッシュからこの行を保存する必要がある出力ファイルのハンドルを取得します。この行をファイルに書き込みます。
以下は、最初の2つのフィールドに一致するいくつかのサンプルコードです。
#!/usr/bin/perl
use strict;
use warnings;
my %filehandles=();
my $filenum=1;
open INPUT, "fruit.csv"
or die "Cannot open input file.";
my $header = <INPUT>;
while ( <INPUT> )
{ # Remove spaces from input
$_ =~ s/ //g;
my @fields = split ',', $_;
if ( ! $filehandles{$fields[0]}{$fields[1]} )
{ open $filehandles{$fields[0]}{$fields[1]} , ">file$filenum"
or die "Cannot open output file file$filenum.";
print {$filehandles{$fields[0]}{$fields[1]}} $header;
$filenum++;
}
print {$filehandles{$fields[0]}{$fields[1]}} $_;
}