重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

テキストファイルの行を文字数順にソートしたいのですが、
sort コマンドを使って行うことはできないのでしょうか?
$ perl -e 'print for sort { length $a <=> length $b } <>' foo.txt
でもいいのですが、行数が膨大なため、できるだけ早く処理したいと思っています。
もし何か方法がありましたら教えてください。お願いします。

A 回答 (3件)

考え方としては、長さと行データをペアにしたデータを作って、それを長さをキーにしてソート。

その後で長さ部分を削除。

簡単に書くなら、Rubyならそのあたりを自動的にやってくれます。
ruby -e 'puts $stdin.readlines.sort_by{|x|x.length}' < foo.txt >bar.txt
    • good
    • 0
この回答へのお礼

大変参考になりました。
これで道が開けました。
やってみます。ありがとうございます。

お礼日時:2008/11/25 19:53

どのくらいの行数を想定していてどのくらいの速度が欲しいのでしょうか?


例えば, そのスクリプトだと比較のたびに文字数を調べてますが, 「各行の文字数を調べる」という処理は 1回で十分です. そうすると, ちょっとは速くなるかもしれない.
いずれにしても本質的に処理は現在と変わらないんだけどね.

この回答への補足

10億行4GiB程度で、最悪の場合でも丸1日以内に終わらせられるような方法を考えています。
ANo.3さんの方法を使ってみたいと思います。
ありがとうございました。

補足日時:2008/11/25 19:50
    • good
    • 0

速度がクリティカルなら、専用のフィルタを作ればいいのでは?


正味30行ぐらいの簡単なサンプルコードを示します。

#こういうの出しておけば、もっとプロな方が、よりよいコードを書いてくれたりして・・・

---------------------------------------
/* mysort.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXCHARS 256
#define MAXLINES 1048576

typedef struct _indata_{
int n;
char line[MAXCHARS];
} indata;

int comp(const void *a, const void *b){
return(((indata *)b)->n - ((indata *)a)->n);
}

int main(void){
int i=0;
indata *buf;

buf = (indata *) malloc(MAXLINES*sizeof(indata));

while(!feof(stdin)){
if (fgets(buf[i].line, MAXCHARS, stdin)==NULL) break;
buf[i].n = strlen(buf[i].line);
i++;
}

qsort(buf, i, sizeof(indata), comp);
for (;i>0;i--){
printf(buf[i].line);
}

return 0;
}
---------------------------------------

$ make mysort
$ cat foo.txt | ./mysort
    • good
    • 0
この回答へのお礼

やってみます。
ありがとうございます。

お礼日時:2008/11/25 19:49

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!