ASH | サーバ | セキュリティ | Linux | FreeBSD | DB | Web | CGI | Perl | Java | XML | プログラム | ネットワーク | 標準 | Tips集

PerlでCSVファイルをソートする方法

 PerlでCSVファイルをソートする方法について、サンプルプログラムを使って説明します。
 ASHのホームページで公開しているスクリプトの著作権はASHにあります。 スクリプトの利用や改造は、非商用、商用にかかわらず自由です。 ただし、利用される場合は、ASHへのリンク、ASHに対するカンパ、ASHに対する仕事の依頼などをお願いします。 ASHではスクリプトの作成も行っています。

CSVファイルのソート処理スクリプト

 Perlのsort関数を使って、CSVファイルのソートを行います。 Perlのsort関数は、ソートサブルーチンを指定できますので、この機能を使います。 CSVデータの任意の項目をソートキーとしてソートします。 キーの数は、無制限ですので、2次キーや3次キーを指定することもできます。 ソート方法は、各キー毎に、昇順ソートと降順ソートができます。 また、文字列ソートと数字ソートが可能です。 1,5,10をソートした場合、文字列ソートでは、1,10,5となりますが、数字ソートでは、1,5,10となります。
 オプションの指定は、スクリプトの先頭で変数に代入することで指定します。 CSVファイル名とソートキーの指定を行います。
 ソート結果は、標準出力にCSV形式で出力します。

sort_csv.pl
#!/usr/local/bin/perl
#
# csvデータのソート
#

{
  # パラメータの設定
  $file = 'data.csv'; # csvファイル名
  $key_num = 2;    # キーの数
  $key_idx[0] = 0; # キーのカラム番号
  $key_dir[0] = 1; # 0:昇順 1:降順
  $key_typ[0] = 0; # 0:文字 1:数字
  $key_idx[1] = 1; # キーのカラム番号
  $key_dir[1] = 0; # 0:昇順 1:降順
  $key_typ[1] = 0; # 0:文字 1:数字

  # csvファイルのオープン
  unless (open (INF, "< $file")) {
    print "Read open error ($file).\n";
    exit (1);
  }

  # CSVファイルの読み込み
  @tbl = ();
  for ($line = 0; ; $line++) {
    tr/\r\n//d;
    @rec = split(',');

    $colm = 0;
    foreach $fld (@rec) {
      $tbl[$line][$colm] = $fld;
      $colm++;
    }

    @idxtbl[$line] = $line;
  }

  # csvファイルのクローズ
  close(INF);

  # ソート
  @idxtbl = sort tblsort @idxtbl;

  # ソート結果表示
  $line_max = @tbl;
  $colm_max = @{$tbl[0]};
  for ($line = 0; $line < $line_max; $line++) {
    for ($colm = 0; $colm < $colm_max; $colm++) {
      if ($colm) { print ","; }
      print "$tbl[$idxtbl[$line]][$colm]";
    }
    print "\n";
  }
}

sub tblsort {
# 比較関数
#   $a < $b : -1
#   $a > $b : 1
#   $a = $b : 0
  my ($i, $idx, $stat);

  $stat = 0;
  for ($i = 0; $i < $key_num; $i++) {
    $idx = $key_idx[$i];

    if ($tbl[$a][$idx] lt $tbl[$b][$idx]) {
      if ($key_dir[$i]) { # 降順
        $stat = 1;
      } else { # 昇順
        $stat = -1;
      }
      last;

    } elsif ($tbl[$a][$idx] gt $tbl[$b][$idx]) {
      if ($key_dir[$i]) { # 降順
        $stat = -1;
      } else { # 昇順
        $stat = 1;
      }
      last;
    }
  }

  return($stat);
}


Copyright (C)1995-2002 ASH multimedia lab.
mail : info@ash.jp