前回に続いて、CGIじゃないPerlの使い道。
正規表現が使える等、文字列の扱いに定評のあるPerlですが、
今回はそこまで行かない数値テキストデータの扱い例。

こんなデータファイル「input.txt」があるとして、
10 5 1
20 10 2
40 15 3 
80 20 4

列ごとに連番、最後に行ごとの平均を加えた「output.txt」を出力します。
001 : 10 5 1
002 : 20 10 2
003 : 40 15 3
004 : 80 20 4
AVR : 37.500000 12.500000 2.500000

実行コマンドはこんな感じで。
> hoge.pl input.txt output.txt

以下、ソース。
Perlでは#でコメント。
#コマンド引数チェック
#Cとは引数ARGVの数え方が違うので注意
if(@ARGV != 2){
    #ちなみに1行だとしても括弧{}を省略できません
    printf("usage: hoge.pl <input> <output)>");
    exit();
}
open(INPUT, "<$ARGV[0]");   #入力ファイルオープン
open(OUTPUT, ">$ARGV[1]");  #出力ファイルオープン
seek(INPUT, 0, 0);          #ファイルの先頭へ
seek(OUTPUT, 0, 0);         #開きたてならいらないけど一応

@in1;       #入力ファイルのデータを格納する配列
@in2;       #行ごとに用意してみた
@in3;       #配列の大きさは指定不要!
$line = 0;  #桁数カウント変数

#入力ファイルデータを記憶
#ファイル末尾に達するまで列ごとに読み込みループ
while(<INPUT>){
    @read = split;    #読み込んだ列を空白文字で分割&配列に代入
    if(@read == 3){
        $in1[$line] = $read[0];
        $in2[$line] = $read[1];
        $in3[$line] = $read[2];
        $line++;
    }
}

#平均値計算
@avr = (0, 0, 0);    #平均格納配列の初期化
for($i = 0; $i < @in1; $i++){
    $avr[0] += $in1[$i];
    $avr[1] += $in2[$i];
    $avr[2] += $in3[$i];
}
$avr[0] /= $line;    #入力データの桁数分
$avr[1] /= @in2;     #桁数と同じ要素数になっているはずなので、
$avr[2] /= @in3;     #←これでも同じはず

#ファイル出力
for($i = 0; $i < $line; $i++){
    #連番は1から出力とする
    printf OUTPUT "%03d : %d %d %d\n", $i+1, $in1[$i], $in2[$i], $in3[$i];
}
printf OUTPUT "AVR : %f %f %f\n", $avr[0], $avr[1], $avr[2];

close(INPUT);
close(OUTPUT);
exit;
あまりスマートでない&安全でない部分もありますが。
とりあえず$は変数、@は配列です。
if文とかで@を指定していますが、これは配列の要素数を見てます。
とりあえず変数の型や配列の大きさの宣言をすっ飛ばせるのが楽。
(場合によっては注意も必要ですが)

whileループの部分も知らないと「splitって何を代入してんの?」という感じですね。
ここでは省略していますがsplitの分割方法は正規表現で指定できます。
もちろん分割元の文字列も指定可です。
@array = split(/ |\t/, $var, 3);
スペースかタブで分ける、"3"は最大分割数の指定。