こんにちは、山本です。
"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/