ハッシュを使った集計結果の出力について
testフォルダに以下のファイルがあるとします。
aaa_1、aaa_2、bbb_1、bbb_2、ccc_1、・・・
各ファイルには○△×がついた行があり、
「aaa」のファイル(aaa_1とaaa_2)の○△×の数、「bbb」のファイルの○△×の数、を集計したいと思っています。
出力イメージは以下です。
ファイル名の一部,○の数,△の数,×の数
aaa,13,59,37
ファイル名の一部をキーとして、
○△×の回数を値にしたハッシュで集計しようとしましたが、
以下のようになってしまいました。
,0,0,0
,0,0,0,0,0,0
aaa,13,59,0
aaa,13,59,0,13,59,37
bbb,20,10,0
bbb,20,10,0,20,10,30
ハッシュが十分に分かっていないので、おかしなことをしてるのだと思うのですが。。
ご教授くださいますよう、お願いします。
opendir(DIR, $dir);
while ($file = readdir(DIR)){
$maru =0;
$san =0;
$batu =0;
$file =~/(.*)_(.*)/;
$name = $1;
open(IN, "$dir/$file");
while ( $line = <FIN1> )
{
chomp( $line );
if($line =~/○/){
$maru++;
}elsif($line =~/△/){
$san++;
}elsif($line =~/×/){
$batu++;
}
}
push(@{$test{$name}} , $maru,$san,$batu);
@gyou = ( $name , join ("," , @{$test{$name}})) ;
print OUT join (",", @gyou). "\n";
}
close (IN);
close (OUT);
No.1ベストアンサー
- 回答日時:
> aaa,13,59,0
→ aaa_1の内容 これは予定通りのはず。
> aaa,13,59,0,13,59,37
→ すでに、この前に $test{'aaa'}として aaa_1の $maru,$san,$batu のリストが存在している。
それに aaa_2の$maru,$san,$batuを push(@{$test{$name}} , $maru,$san,$batu);として「追加」しているのだから
$test{'aaa'}=[
aaa_1の$maru,
aaa_1の$san,
aaa_1の$batu,
aaa_2の$maru,
aaa_2の$san,
aaa_2の$batu
];
となります。
これをjoinで継げて表示すれば、当然、その実行結果の通りになる。
pushはリストに「新しい要素を追加する」のであって、「既存のリストの要素に加算する」ものではありません。
期待するものにするならば、
$test{$name}[0] += $maru;
$test{$name}[1] += $san;
$test{$name}[2] += $batu;
と、それまでの値に新しい値を「加算」しなければ。
>,0,0,0
→ $file =~/(.*)_(.*)/; がマッチしないファイル名のため、$nameが空文字列''になっている
readdirには . (カレントディレクトリ)や .. (一つ上のディレクトリ)も含まれる。
if ( $file !~/(.*)_(.*)/ ) { next ; }
などとして、マッチしないファイルは処理を飛す必要があります。
>,0,0,0,0,0,0
上のaaa_2のケースと同じ。おそさく ,0,0,0ではカレントディレクトリ, ここでは親ディレクトリを処理している。
あとは
・$dirはどこから出てきた?
・FIN1はどこから?
・OUTはどこから?
・close IN の位置がおかしいのでは? while ( $line = <FIN1> )のループの終了直後だと思うのですが。(FIN1がINだとして)
・aaa_1のときとaaa_2の時の2回 aaaが表示されるが、それでいいの?
おそらく、こんなのを求めているのでは?
$dir= "." ; #検索ディレクトリ
opendir(DIR, $dir) ;
while ($file = readdir(DIR)){
if ( ! -f $file ) { next;} #ファイルで無い場合は無視
if ( $file !~/(.*)_(.*)/ ) {next;} #非該当ファイルは無視
$name = $1;
if ( ! defined( $test{$name} ) {
# 新しい名前だったら初期化する
$test{$name}=[0,0,0] ;
}
open(IN, "$dir/$file");
while ( $line = <IN> ){
# chomp( $line ); #chomp必要ですか?
if($line =~/○/){
# $maru++; と別変数に入れて後で足すくらいなら、
$test{$name}[0] ++ ; #と最初から足せばよい
}elsif($line =~/△/){
$test{$name}[1] ++ ;
}elsif($line =~/×/){
$test{$name}[2] ++ ;
}
}
close IN ; #whileが終れば、ファイルは入力済み
}
#全ファイル終了
closedir DIR ;
open(OUT,"output.txt"); #出力ファイル
foreach $name (keys %test) {
print OUT join (",", $name, @{$test{$name}}) . "\n";
}
close OUT;
ご回答ありがとうございます!
pushでは加算できないんですね。確かにそうですよね。。
readdirも適当に使っていたのでとても勉強になりました。
基本的なところから勉強し直さなくては。
あ、ディレクトリは引数で指定するつもりでしたので、それが$dirになります。
(perlの内容全てを書いていませんでした)
説明も丁寧で大変役に立ちました。本当にありがとうございました。
できるようになりました!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Perl perl このテキストファイルを簡単に配列に入れるには? 2 2022/04/27 20:24
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- UNIX・Linux Linuxについて質問です。 以下のhistoryの出力結果から、sedコマンドのファイル名tmp1 1 2023/02/03 20:11
- Excel(エクセル) Excel VBA 3 2023/04/22 10:46
- Excel(エクセル) ¥マークを含むパスの処理について(マクロ、または関数) 2 2022/12/25 02:11
- Visual Basic(VBA) 集めたシートのシート名を変更したい。 下記のコードでサブフォルダにあるファイルのSheet3を集めて 6 2022/08/23 10:38
- SQL Server ACCESSで3ファイルを結合して、表を作成するやり方を教えて下さい。 17 2022/08/15 20:34
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- その他(プログラミング・Web制作) bashのgrepで複数の検索、かつスクリプト内で改行する方法を教えてください。 1 2022/10/06 20:09
- その他(Microsoft Office) パワークエリの複数ファイルのデータ統合について 3 2022/07/14 17:06
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
テキストファイルで提出とは?
-
ターミナルで特定の文字と文字...
-
Perlでの文字列置換
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
ファイルアイコンの左下に緑の□...
-
perlプログラミング 空白行削除
-
perlのrequireの動き方について...
-
ペプシコーラとコカ・コーラとD...
-
perlについての質問
-
perl このテキストファイルを簡...
-
Perlでファイルの末尾から指定...
-
Perlで特定文字列から特定文字...
-
Perlのプログラムについて
-
CGIでimgタグでalignを使うとエ...
-
openした後、closeしないでプロ...
-
perl 初等プログラミングについて
-
Windows版のPerlについて
-
このファイルを開く方法で困っ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
INDIRECT 横に再度抽出したい
-
perlをバージョンアップしたら...
-
openした後、closeしないでプロ...
-
Perlで特定文字列から特定文字...
-
Wallpaper Engineでおすすめの...
-
Perlのエラーについてご教授く...
-
アルファベットに付いて質問し...
-
Strawberry Perl for Windows ...
-
bashスクリプト
-
テキストファイルで提出とは?
-
Perl の外部モジュールの利用方法
-
#!/usr/bin/perlで書きだしたCG...
-
Windows10においての『Perl』の...
-
perlのflock関数でロックをかけ...
-
perlで2次元配列をサブルーチ...
-
Perlで時間の計算
-
perlのrequireの動き方について...
-
画像が表示でnull; this.src
-
ターミナルで特定の文字と文字...
-
英数文字列のうちの数値を4桁に...
おすすめ情報