• ベストアンサー

文字数順にソートするには

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

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

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4900/10359)
回答No.3

考え方としては、長さと行データをペアにしたデータを作って、それを長さをキーにしてソート。その後で長さ部分を削除。 簡単に書くなら、Rubyならそのあたりを自動的にやってくれます。 ruby -e 'puts $stdin.readlines.sort_by{|x|x.length}' < foo.txt >bar.txt

_--_--_-_-
質問者

お礼

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

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

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

_--_--_-_-
質問者

補足

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

  • astronaut
  • ベストアンサー率58% (303/516)
回答No.1

速度がクリティカルなら、専用のフィルタを作ればいいのでは? 正味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

_--_--_-_-
質問者

お礼

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

関連するQ&A

専門家に質問してみよう