- ベストアンサー
Perl ファイルを読込んで日付の降順に並べ替えるには?
お世話になります。 次の様な内容ファイルを読込み ===================== "No" "accessday" "1" "2007/1/10" "2" "2007/1/2" "3" "2007/1/5" "4" "2007/1/11" ===================== 日付の降順に並替えて下記のように表示したい場合 ===================== "No" "accessday" "4" "2007/1/11" "1" "2007/1/10" "3" "2007/1/5" "2" "2007/1/2" ===================== どの様なコードを書けばよいのでしょうか。 出来れば簡単なコーディング例などで解説お願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
#!/usr/local/bin/perl open FILE, 'test.txt'; @lines = <FILE>; close FILE; @sorted_lines = sort {sort_value($b) cmp sort_value($a)} @lines; print @sorted_lines; exit; sub sort_value { if($_[0] =~ m|"(\d+)/(\d+)/(\d+)"|){ return sprintf("%04d%02d%02d",$1,$2,$3); }else{ #タイトル行は先頭に来るように return '99999999'; } } ソート用の関数で日付の桁をそろえて、それを元にsortしてます。 "2007/1/10" → "20070110" "2007/1/2" → "20070102" こんな感じでどうでしょう?
その他の回答 (1)
- sakusaker7
- ベストアンサー率62% (800/1280)
sort のブロックの中で何度も同じ処理を行うのはソート対象のデータ数が多いと 処理時間に利いてきますので、こういうやり方もあるよということで。 #Schwartzian Transformは自粛 use strict; use warnings; my @data = <DATA>; my $header = shift @data; my %work_for_sort; foreach (@data) { my ($year, $month, $day) = m{"(\d+)/(\d+)/(\d+)"}; if (defined $year && defined $month && defined $day) { my $l = sprintf "%04d%02d%02d", $year, $month, $day; $work_for_sort{$_} = $l; } } my @sorted = sort { $work_for_sort{$b} cmp $work_for_sort{$a} } @data; print $header; print @sorted; __END__ "No" "accessday" "1" "2007/1/10" "2" "2007/1/2" "3" "2007/1/5" "4" "2007/1/11"
お礼
ご回答ありがとうございました。 2通りの回答例を見せていただきましたが、 シンプルに元データを "2007/1/5" なら "2007/01/05"と保存するようにして ソートをかけるという様にしました。 またよろしくお願いします。
お礼
あっそうか!と気がつきました。 元データを作成するときに $accessday = sprintf("%04d/%02d/%02d", $year, $mon, $mday) として、2007/1/2" ではなく "2007/01/02" と保存するように 変更しました。 これでソートしてばっちりでした。 ありがとうございました。