作者: Koichi Yamamoto
日時: 2004/2/5(10:41)
こんにちは、山本です。

"HFC01730@... (水羽信男)"さんは書きました:
> # 入力・出力データの形式は、以下のとおり
> # 1/李広田/りこうでん
> # 2/王迅中/おうじんちゅう
> proc sortfield3 {filename column encoding} {
>      set fd [open $filename] 
>      fconfigure $fd -encoding $encoding
> 
>     set data [read $fd 1]
>     if [string equal $data \ufeff] {
>         set data [read $fd]
>     } else {
>         append data [read $fd]
>     }
>     close $fd
>     foreach i $data {lappend data2 [split $i /]}
>     set data3 [join [lsort -index $column $data2] \n]
>     puts [regsub -all -line \  $data3 /]
> }

> いまのところ期待通りの動作なのですが、データファイル
> が大きくなるとここが問題だ、とか、何か気づかれた点が
> あれば、ご教示いただければ、幸甚です。

確かに上記のデータであれば期待通りの動作はしますが、
次のようにwhite spaceが含まれると正常に動作しなくなります:
    1/李 広田/り こうでん
    2/王 迅中/おう じんちゅう

15行目以降を以下のように修正してください:
    foreach i [split [string trim $data] \n] {lappend data2 [split $i /]}
    foreach i [lsort -index $column $data2] {lappend data3 [join $i /]}
    puts [join $data3 \n]

Tclでのリストはwhite spaceで単語を結合して表しますが、
単語の中にwhite spaceが含まれると、次のように { } で
単語が括られてしまうため、regsubで半角空白を / に置換した
だけでは期待した通りの結合ができないのです:
    split "aaa/bbb ccc/ddd" / → aaa {bbb ccc} ddd
    join {aaa {bbb ccc} ddd} / → aaa/bbb ccc/ddd

ちなみに、Tclではdouble-quote(")とbrace({ })はどちらも
単語を括るという点においてほとんど同義です。これらの
違いは単語の中にあるコマンド置換([ ])や変数置換($)、
バックスラッシュ置換(\)を行うか否かという点です。
私はbrace記号はPerlのsingle-quote(')に似た機能と
認識しています。

--
Koichi Yamamoto, 
http://homepage3.nifty.com/yamakox/