• ベストアンサー

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" ===================== どの様なコードを書けばよいのでしょうか。 出来れば簡単なコーディング例などで解説お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • venzou
  • ベストアンサー率71% (311/435)
回答No.1

#!/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" こんな感じでどうでしょう?

souta_n
質問者

お礼

あっそうか!と気がつきました。 元データを作成するときに $accessday = sprintf("%04d/%02d/%02d", $year, $mon, $mday) として、2007/1/2" ではなく "2007/01/02" と保存するように 変更しました。 これでソートしてばっちりでした。 ありがとうございました。

その他の回答 (1)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

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"

souta_n
質問者

お礼

ご回答ありがとうございました。 2通りの回答例を見せていただきましたが、 シンプルに元データを "2007/1/5" なら "2007/01/05"と保存するようにして ソートをかけるという様にしました。 またよろしくお願いします。

関連するQ&A

専門家に質問してみよう