むさいさん、こんにちは。 ここで新しいスレッドを起こすことでもないようにも思ったのですが、何だか 今日はやけにあっちもこっちも繋がりが悪くて…。さて、これは上げられるのか な? 軟体計画のリンク先、重いところの情報を金野さんに伝えてしまってすいませ んでした。それにしても、大変なことをやってしまいましたね。ほんとうにご苦 労様でした。文化は引き継がれていくと思いますし、多くの人が恩恵にあずかれ ると思います。Nifty で僕が最後にログのライブラリーをみたとき、25人くら いが落としてましたので、それぐらいのVzerは生存しているのだと思います。 とにもかくにも、ありがとうございました。m(__)m あ、遅ればせながら、BBS開設おめでとうございます。
ども,お久しぶりです。DC 消滅からはやひと月ですね。 和生師匠の消息を案じつつ,ここで淡々と続けてます。 軟体補完計画のリンク先は,まだあれだけなんですから仕方ないですよね。 別にそんな些細なことを謝らなくてもいいじゃないですか。「大変なこと」と おっしゃいますが,粛々とやっているだけですよ。それにしても,マクロ師の 営みというのはリストにしただけでもとんでもない量で,改めてそのエナジの 凄さを確認しました。 これから,徐々に整備していきますので,誤謬のご指摘や,形式の提案など いただけるとありがたいです。よろしくお願いします。 目下の悩みは,,,全然マクロの話が始まらないこと。(^_^; どっちかと言うと,わたしは餌に飛び付く方だったので…。 ところで,こちらでは「めざら」でお願いしますね。(^^ゞ
めざらさん、こんにちは。ああ、ハンドルを…?! ということは、むさいさんは、もう出番がないんですかねぇ。そいういえば、 耳而夢斎ってFEPに単語登録してあった…! 確かに、和生さん(「わなま」で登録済み)は、ネットの世界はあんまり食指 が動かない(面倒、かな?)んですかね。YASAT さんは、明らかに、出づらい、 という感じだったと思いますけれど。皆さん、いらっしゃいませな。> 軟体補完計画淡々と粛々のたまものですねぇ。すごい。> これから,徐々に整備していきますので,誤謬のご指摘何か気がつくことがありましたら。> 目下の悩みは,,,全然マクロの話が始まらないこと。(^_^;確かに。 逆順テキストの比較(by としき)は、どんなアルゴリズムを考えら れますか? 僕なら行単位という制限付けて、#69 を使ってやるかなぁと考える だけ考えましたけど。1文字ずつ cd 比較するのはなぁ、と(=窓二つのあいだ でバンバン、カーソルを飛ばし続ける)。 いえ、これがかなり汎用性の低い機能だとは思うのですが、でも、割としょっ ちゅう汎用性はないけど、作業論理はかなり機械的なのに、その手のマクロがな い(汎用性低いから当たり前)とか思うことがあるんですよね。うん、たとえば、 sed のグローバルでない置換とか、序数指定(何番目という意味)の置換とか。 これらの存在を知ったときには、元のプログラム(この場合 sed)の都合で存在 してる機能だと思っていたのだけど(そうなのかもしれない)、でも、使う場面 があり、Vzマクロで簡単にいかないなぁ、とか思いました。
そもそも「むさい」ってのもハンドルのニックネームだもんね。 申し訳ないですが,ここではめざら統一でお願いします。> 確かに、和生さん(「わなま」で登録済み)は、ネットの世界はあんまり食指> が動かない(面倒、かな?)んですかね。YASAT さんは、明らかに、出づらい、> という感じだったと思いますけれど。皆さん、いらっしゃいませな。和生さんには1月に近況を知らせる葉書をいただいて,「めざら資源で面倒 みる気ありませんか?」って言われていたのです。その時点ではここに掲示板 を設置するなんて気はさらさらなかったのですが,和生さんが来てくださるな らと思って, 2月に CGI と格闘(って言うか勝手にもがいていた)してみた というわけです。YASAT さんは,ご自宅に環境がないようで,なかなか面倒な ことになってしまうようですね。> 確かに。 逆順テキストの比較(by としき)は、どんなアルゴリズムを考えら> れますか? 僕なら行単位という制限付けて、#69 を使ってやるかなぁと考える> だけ考えましたけど。1文字ずつ cd 比較するのはなぁ、と(=窓二つのあいだ> でバンバン、カーソルを飛ばし続ける)。効率を考えると1行単位になるのはいいとして,#69を使うと, その行以降 をすべて比較してしまいますから,どこかのバッファに双方の行を複写して, お尻から(お,これは得意だ)バッファ上で比較することになるでしょうか。 でもメモリ上の比較もせっかくある文字列比較関数を使わないでやるとなると, それなりの時間がかかるでしょうね。それと2バイト文字の後ろ手(おっと緊 縛モード(^^;)後ろで引っ掛かったときにどうするかとか,問題があります。 あと,確保するバッファのサイズとか。テキストバッファに直接アクセスする 手法ならサイズ問題はないでしょうが,もはやマクロとは言いがたいかも。 結論としては,複窓間でカーソル飛ばしが現実的かもしれませんね。スピー ドの問題はあるけれど,メモリ上でやる方法に決定的に美しい方法が見つから ないのであれば,泥臭い方を選択しても同じ。 簡単に裏返す方法があれば,…といってもやはり文字単位だから並べ替えを しなくちゃいけないですね。これって,アルゴリズムのいいのがないと決定打 は出ないのではないでしょうか。
めざらさん、こんにちは。 確かに、カーソルバンバン飛ばし以外は「もはやマクロでない」ということに なりそうですね。#69 作戦も、おっしゃるとおり「カーソル位置から」の条件が うまくいかなくなりますね。僕の念頭にあったのは、ほとんど差異のないファイ ルを対照するというので、カーソル位置より下に違いが《すでに》あるファイル (これだと #69 で確かにひっかかる。 それは無視といっても駄目だ。行番号を 覚えさせておけば、無視させられるかな?)だと困難。いずれにせよ、なんだか 制限が多そうだ。 斬新なアイディアとしては、一度2つの比較ファイルの中身を全部ひっくり返 してしまっておく、というもの。げ、野蛮。rev という unix-like tool で行の 反転はできます。 探したけどちょっと見つからなかったのですが、確か tac と かというツールで行内の文字順を反転することができたので(sed でもできる)、 これでやれなくはないだろうけど…。こっから先は汎用性とプログラミングする 動機づけの問題かな…。>こっちにもってきてしまって申し訳ないけど、どうで す? >としきさん やっぱ、カーソルバンバン飛ばしcd比較が、現実的な解になりそうですね。 s/a/b/ とか s/a/b/3 に該当するVzマクロについてはアルゴリズム・アイディア浮かびますか? filter.def で素直に sed が正解なので、これはあまり面白くないですが、ど うして必要だったかを書いておくと(割と汎用的な話)、複数タブで区切られて いたデータのある第1フィールド末に括弧を付けたかったのです(こう書くと awk だけど)、で最初のタブを「\t」→「》\t」(置換文字列で \t は一般的に 駄目ですが)とかで解決だな、と思ったのですね、この場合。 うん、つまらない話になってしまった。
> やっぱ、カーソルバンバン飛ばしcd比較が、現実的な解になりそうですね。結論としては、そんなもんですかね。 私も2つのファイルを行ったり来たり、というのは考えるだけは考えたのですが、 いくらなんでも、という思いがあって、もっといいものを誰か作っていないかと 質問させてもらったのです。> 斬新なアイディアとしては、一度2つの比較ファイルの中身を全部ひっくり返これは確かに斬新ですね。 わたしには思いつきもしませんでした。 ただ、斬新すぎて、よく理解できません。 これって行毎に反転するんですか、それともファイル丸々反転させるの?> してしまっておく、というもの。げ、野蛮。rev という unix-like tool で行の> 反転はできます。 探したけどちょっと見つからなかったのですが、確か tac とrevは私も持っていて、最近よく使うようになったのですが、これだと行毎にしか 反転できませんよね。あ、私の使っているバージョンは、私のサイトのソフトウェア ライブラリで紹介しているsortに同梱されているものです。 tacってツールは知らないのですが、どんなものなんだろう?> これでやれなくはないだろうけど…。こっから先は汎用性とプログラミングする> 動機づけの問題かな…。>こっちにもってきてしまって申し訳ないけど、どうで> す? >としきさんなんか呼びつけられてしまっていますが。(笑) ちょっと今日はもうこれ以上コンピュータ関係のことで頭を使いたくない感じ。 なぜって、今日は私、情報処理技術者の試験を受けてきたもので。 #グレードはデータベースというやつ #去年も同じものを受けて玉砕している #今年はもっとできが悪い いや、実は私、ここってめざらさん作のマクロのサポート掲示板だという思いが 強くて、だから意図的に、新しいマクロに関するネタ振りはこちらでは避けて いたりするのです。別にそんなにこだわることもないのでしょうが。 でも、万が一、私のサイトの掲示板で私の作品以外のマクロネタが出てきたり したら、多分よそのサイトに誘導すると思います。
http://www.linux.or.jp/JM/html/gnumaniak/man1/tac.1.htmlより> tac は指定されたファイルの内容を標準出力に書き込む。その際、レコードを逆> 順にする ( レコードのデフォルトは行単位 )。FILE が一つも与えられないと標> 準入力から読み込む。 また FILE が` -' だった場合には、そのファイルには標> 準入力が用いられる。これは、revと同じではないか? もちろん意図したのは、行をひっくり返し、文字もひっくり返すなので あいうえお かきくけこ が こけくきか おえういあ となるような操作です。行内の文字を全部ひっくり返す、なんて、ほんと何に使 うの? というツールなんてないか??? 試験、お疲れさまです。
文太さんの発想がなんとなくわかりました。 ところでtacなんですが、紹介いただいたページを見て私が理解したところでは、 tacってcatの反対なんですよ。つまり、 あいうえお かきくけこ という入力を かきくけこ あいうえお と言うように、最後に入力されたレコード(行)を最初に出力し、最初に入力された 行を最後に出力するんですよ。なので、> もちろん意図したのは、行をひっくり返し、文字もひっくり返すなのでということであれば、tacとrevを両方使ってやればいいことになりますね。 revって、行毎に行内の文字を反転させるものですから。 でも、私の使っているrevは日本語対応になっていないので、1バイトごとに反転 してくれるため、かなり不便。
−−−C:\UTOOL\MAN\REV.MANより−−−> rev とは、BSD系UNIXの同名コマンドの模倣で、入力ファイルの各行ごと> に、それを逆順にして(行末から行頭の順に)出力する。本アーカイブに> 所収のコマンドのうち唯一、作者も何のために使うのかわからないコマ> ンドである:-)。次のオプションを持つ。−−−−−−−−−−−−−−−−−− 仰るとおり。 そうそう、その野蛮な発想です。でもrev、使い道あるじゃん。 revでボタンの掛け違いが始まったのですね。 unix-like toolsのrevはawkで実現されているはずで、jgawkを使えば2バ イトもOKなはずですね。 ま、素直に1文字ずつcdで比較、がやっぱりいいのでしょう。 いやいや、どんな使い道? なツールも、使い道があるもんですね。あと、 何だっけ? ものすごく機械的なスクリプトを書いているときによく思うも のだったのだけど…。 日本語の通るtacって、ないですかね?
> 日本語の通るtacって、ないですかね?ふと思いつきました。 tac は sed スクリプトで可能で、日本語の通る sed を使えば、別に日本語対 応の tac が必要というわけではありませんでした。 rev は、nide さんの unix-like に入っているもの。jgawk で使えば、2バイ ト文字も問題なし。>Sed -f tac.sed test.txt |Rev -j---tac.sed---#sed.shdより。読めてませんので安易に質問しないでください。 1!G h $!d ------------- あいうえお かきくけこ ↓ こけくきか おえういあ という具合です。(意味ないと思うけど…。)
>としきさん、すいません。 何をやっているのだか…。 1!G #(1)最初の行でなければHSをPSにアペンド h #(2)PSをHSに上書きコピー(作業開始) $!d #(3)最終行でないなら、PSをdel。最終行以外では新たにサイクル #が始まる。最終行では、PSのdelが行われず、新サイクルも始ま #れないので(=入力がない)、PS全部=蓄積されてきた行逆順 #の全部の行がprintされる。 ※ PS=pattern space HP=hold space(保存バッファ) もしスローモーションで全体の動きを映像化すると、 (1)(2) が目に見える動 きとして繰り返されているのが主な動き。といっても、サイクルとしての新行の 読み込みが映像化できないと苦しいが(これは、(3) と (1) のあいだで起こる)。 PSにそれまでの行が後ろからアペンドされていくのが (1)。 アペンドされた(ひっくり返った行(複数)が)HSに保存されるのが (2)。 (繰り返し) 逆順の行が次々生成されていくのはPS内(G によって)。それが生成される とすぐさまHSに保存される(h によって)。ただし、この保存は次のサイクル でもっとも新しい逆順行をつくるためになされている点がポイント。次のプロセ スがない場合=最終行だった場合には、保存に意味はなく、ただPSが吐き出さ れる。 1!G #(1)最初の行でなければHSをPSにアペンド h #(2)PSをHSに上書きコピー(作業開始) $!d #(3)最終行でないなら、PSをdel。最終行以外では新たにサイクル 1!, $1 というアドレッシングは、割とよくあるパターンなんですが(ペアに なる場合もそうでない場合も)、このアドレッシングがないとどうなるかだけ書 いておきます。 1!G は、G だけだと、最初の行でも G してしまいますので(HSが空なのに)、 最終結果のファイル先端に、どっから来たのよ、という改行が1つよけいに付い てしまう(こういう仕様なんです=逆手によく使われる=ダブルスペース化とか)。 $!d は、d だけだと、最後の行読み込み後でもこれが効いてしまうので、何も 出力されなくなってしまう。最新の逆順行の結果はPSに保存されているからで す。 たったあれだけのスクリプトを解析するのに、こんなにかかってしまった。 最初、あれだけでこんなにできるの?! と面白がったのですが、sed はパイ プです。見えません。見えない部分が見えるようにならないと、難しいことはで きない…。 同じことを awk でやっても面白いかもしれない。 Vzマクロ? うん、でき る。でも、なんか違う気がしてしまって…。2つのバッファを用意して(それぞ れ制限を決めて=マクロバッファしかない? 小さいよ)…。sed とロジック同 じにしかできない…。 とやり始めると、XPなら、onigsed なら、ドコモバ+ serow 版 sed なら、 とかなるなぁ。
ども。解説多謝であります。 自分ではホールドスペースを使ったスクリプトなんて数年に1回程度しか 書かないので、見ただけではさっぱりわからなかったのでした。 ただ、今回の目的は、反転させることではなくて、下から遡って相違点に カーソルがジャンプしたら、そこから編集を実行することなので、ちょっ とこのままではこのスクリプトは使えません。ただ、sedではこんなに簡単 にできるということがわかって、とても勉強になりました。> 同じことを awk でやっても面白いかもしれない。{arr[NR]=$0}END{for(i=NR;i>0;i--)print arr[i]} かな? Vzマクロだと、テキストスタックを使う? いや、新しいファイルを開いてしまうのがいいかも。 #N"hogehoge"#mしたあと、#W#k#W#i#W#xを繰り返し。 ファイル終端は#xのステータスをrで捕捉してループ終了。 う〜ん、結構力技。
> ただ、今回の目的は、反転させることではなくて、下から遡って相違点に実にそのとおりですね。m(__)m> 同じことを awk でやっても面白いかもしれない。{arr[NR]=$0} END{for(i=NR;i>0;i--)print arr[i]} 完璧でした。こっちのほうがよほど見渡しがいいのだけど、forが入ると…。> Vzマクロだと、テキストスタックを使う?> いや、新しいファイルを開いてしまうのがいいかも。実にそのとおりでした。基本を外した。どうしてだかメモリーを使うとスマー トで、手の動きがやカーソルの動きが見えてしまい、それがグルグル回っている のが容易に想像できると力技のような気がしてしまう…。エディタというインタ ーフェイスのぶん、無駄が多い、というのは使われているエネルギー(リソース?) を考えると、やはり真実なんでしょうけどね。でも、仕事してくれればいいよう な…、このレベルの作業なら。 マクロは人に楽させてくれるものなので。美しさより、仕事優先の道具。 awk、勉強させてもらいました(何度も言ってる台詞。進歩がない)。
としきさん,試験お疲れさまでした。> 私も2つのファイルを行ったり来たり、というのは考えるだけは考えたのですが、> いくらなんでも、という思いがあって、もっといいものを誰か作っていないかと> 質問させてもらったのです。折衷案はどうでしょう。 A ファイルaとファイルbの末行に移動 B 双方のカーソルを行頭に合わせて比較 C 相違なしなら,#s #< で前の行の行頭に移動してBへ 相違があれば,その位置でブロックモードに入る D 双方のカーソルを行末に移動 E カーソルをバンバン飛ばして行末からcd比較 F 相違点で一旦#d G &d mb-, #] で相違部分の範囲を示す擬似ブロックを残す H おしまい> いや、実は私、ここってめざらさん作のマクロのサポート掲示板だという思いが> 強くて、だから意図的に、新しいマクロに関するネタ振りはこちらでは避けて> いたりするのです。別にそんなにこだわることもないのでしょうが。いや,なんでもありです。新マクロのネタ振りも,連絡のつかない他人様の マクロの相談とかもかまいません。あくまでも出来る範囲で,ですが。
ども。> 折衷案はどうでしょう。まだ頭が寝ているのかな、よく理解できません。> A ファイルaとファイルbの末行に移動> G &d mb-, #] で相違部分の範囲を示す擬似ブロックを残すこの2つが、私の考えていることとうまく符合しません。 上から下へのファイル比較って、先頭行から開始しているわけではないですよね。 それに、不一致を検出したらそこで停止するだけであって、比較機能そのものには ブロックモードか否かというのは関係ないですよね。 私としては、遡り比較も、その点は同様であってほしいのです。 ちょっとむりやり利用シチュエーションを考えました。 例えば、大きなファイルを上の方から順次書き換えていきます。 次の日、続きの作業を開始しようとしたけれど、どこまでやったか忘れてしまい ました。バックアップはあるのですが、上の方から比較していくと、変更点が いっぱいあって比較になりません。そこで、下の方、ま、文末でもいいのですが、 適当に思いついた言葉(例えば「第6章」)を検索してそこまでジャンプして、 そこから遡り比較を始めます。すると、第2章第3節第1項の2の補足の付記で カーソルが止まって、そうか、ここまでやったんだ、ということがわかります。 って、かなり無茶があるなぁ。
なるほど。としきさんの考えていることは,すごーくよく解りました。 #69 の仕様で比較だけを逆方向にするというのは筋が通っています。当然の仕様だ と思います。それをやるなら,やはりカーソル飛ばししかないでしょうね。 ただそこでわたしは(それがいいか悪いかは別として)どうしても現実的な 方向を向いてしまうのですね。現実的な利用シチュエーションを考えてみるわ けです。そこで想像したものは,としきさんのものと【全く】同じです。 つまり,上から順に変更を加えて,どこまでやったか忘れたというケース。 まったく同じ想像をして,形にしたのが次のマクロです。 ----------^ OSAWARI.DEF ( date:2005-04-18 time:12:50 ) -----< cut here = osawari.def = by H_ear #if 0 テキストの逆順比較【おさわり.でふ】 #endif * mad for vz! 1 ^\ "" ?. (wt)??. ;分割モードだけで実行 &s #_ #W #_ ;A ファイルaとファイルbの末行に移動 #< #W #< ;行頭に移動 :B ; ---- main loop ---- #69 ;B 双方のカーソルを行頭に合わせて比較 (r)??{ ;C 相違なしなら前の行の行頭に移動してBへ #s (r)?>z #< #W ;ファイル先頭に到達したら終了 #s (r)?>z #< >B } #b #W #b ; 相違があればブロックモードに入る #> #W #> ;D 双方のカーソルを行末に移動 :C cd[, #W (cd==0])?{ #s #W #s >C} ;E カーソルをバンバン飛ばして行末からcd比較 #d #W #d ;F 相違点で一旦#d :z ; ---- exit ---- &d mb-, #W mb-, #] ;G 相違部分の範囲を示す擬似ブロックを残す . ;H おしまい * [Variables] 未使用 [Buffers] 未使用 [History] 2005/04/18 0.10 としき氏のネタを横取り。とりあえず動くが…。 [Notes] ・巨大ファイルの先頭付近だけ相違があるときは異様に遅いはず ・#69のふるまいの問題:全角/半角でカーソル位置がずれる [Todo] ・実行した側のファイルに終了時のカーソルを戻さなくちゃね。 ・相違がないときは,「一致しました」[&m(24)]って表示させなくちゃね。 ・相違があるときは,「相違があります」[&m(25)]って表示させてもいいかも。 ・一方がファイル先頭に到達したときはいきなり終了でいいわけ? ・お尻から比較だからって,【おさわり】ってネーミングは安易なのでわ。 ・全角/半角混在位置で擬似ブロック位置がずれるのをなんとかしたい。 ----------$ OSAWARI.DEF ( lines:44 ) -----------------------< cut here 終わりの方にも変更点があって,それはともかくカーソル位置から逆順比較 しなければならないケースの場合は,素直に泥臭いカーソル飛ばし cd 比較と いうものを作らざるを得ないでしょうね。 その場合は工夫が必要ないので,ネタとしてはあまり面白くないかも。
> 終わりの方にも変更点があって,それはともかくカーソル位置から逆順比較> しなければならないケースの場合は,素直に泥臭いカーソル飛ばし cd 比較と> いうものを作らざるを得ないでしょうね。やっぱりそうなっちゃいますかね。 でも、私としては、そのほうがいいということがわかりました。 無理やりなシチュエーションその2。 大きいファイルから一部を切り出して、その小さいファイルを上の方から編集。 でも、大きい方のファイルも一部編集実施。 最終的に大きい方へ小さい方のファイルの編集結果をマージ。 ということで、小さい方は文末だけど、大きい方はファイル途中から遡り比較を 行いたい。 作っていただいたマクロは、今夜、仕事の合間にでもテストしてみます。
osawari.def使ってみました。 先頭付近だけ相違のある300KB弱のファイルで試してみたのですが・・・ こりゃあかんわ。想像以上に時間がかかりました。 クロック133MHzの自宅のメインマシンで試してみたというのがいけないのかも しれませんが、でも、このマクロを一番使いたくなると想定されるマシンは、 やっぱり自宅のメインマシンですから。 で、性能的なものはおいといて、機能的なものでいうと、分割モードオンリーと いうのは不便です。#69なら、分割モードでなくても実行可能でしょ? あと、最後に残る擬似ブロックも、私のニーズには合致していませんでした。 下から比較していって、相違がある部分でカーソルが止まってくれるだけで いいんです。後は、メッセージラインに、相違があるかないかを表示して もらえればうれしいかな、と。> その場合は工夫が必要ないので,ネタとしてはあまり面白くないかも。何か、速度向上の工夫っていうのはないでしょうか。
> こりゃあかんわ。想像以上に時間がかかりました。あは (^o^ゞ。やっぱりそうですよね。 同じ箇所を #69で何度もお触りしているのですから,時間がかかって当然で す。当然の予想された反応でございました。たははは。 異なる部分を擬似ブロックで明示するという(余計な)機能を考えたために, 分割でメッセージなしということになってました。#69と全然違いますね。> 何か、速度向上の工夫っていうのはないでしょうか。性能を向上させようと考えると,メモリ上で実行させる必要がありますね。 そうすると,2行分のバッファが必要で,しかもラインバッファは使えない。 内部情報に詳しい人なら,テキストバッファに直接アクセスするようなことを 考えるかもしれませんが,ちょっと無理。 あと大きなバッファとしてはテキストスタックがありますが,かなり面倒な 気がします。相違位置が漢字の2バイト目とかも問題で。 #69も実行後の相違位置指示は2バイト文字に対応していませんが。
osawari が使い物にならないというわけで,新たに作りなおしました。 名前も revcomp.def と,まぁ,少し真面目なものになりました。 一応,お さわりと違って,結構真面目に作っています。 テキストスタックを使うので,比較はメモリ上でということになりますが, 行単位でスタックに読み込むというオーバーヘッドがあります。手元で計測し たところ,celeron/800MHz で 20KB/sec 程度の速度しか出ていないので, ス タックを使っている割には遅いと思います。 でも,わたしにはこのあたりが限界かなー。スタックに数行一遍に読み込む という手もありますが,どのくらい読み込むのが適当か判断が難しいです。 どうぞ試用してみてください。 ----------^ REVCOMP.DEF ( date:2005-04-21 time:21:39 ) -----< cut here = revcomp.def v0.10 = by H_ear #if 0 テキストの逆順比較(スタックに取り込んで比較) #endif * mad for vz! 1 ^\ "" ?. (wa.5+wb.5)?{ &m("ブロックモードでは実行できません") . } &s k=kp, :l ; ---- main loop ---- (lx+lh)??{ #W (lx+lh) #W ?>d ?>b } #b #< #k dz[=kz, a=kp-4, aa=kp..-1, dz], #W ;kp..-1:ブロックサイズ #b #< #k dz[=kz, b=kp-4, bb=kp..-1, dz], #W (aa<=bb)?i=aa, ?i=bb, ;比較回数は小さな方に合わせる r-, dz[=kz, (i){ (a.-r==b.-r)?r++, ?{} } dz], (r==i)?{ 3(k) :b #s i=r, #W #s i+=r, #W (i+2)>?{ >q >d >l } &m("!Error") >z } i=r, #> cp-=i, #W #> cp-=i, #W :d &m(25) >z :q &m(24) :z ; ---- exit ---- 3(k) &d #] . * [Variables] a,b address i counter k kp ptr aa,bb block size [Buffers] 未使用 [History] 2005/04/21 0.10 初版 [Notes] ジョークのosawari.defに比べると,ちょっと真面目に作った。 [Todo] 改行を含んで比較していないのでなんとかしたい。 実行後のカーソル位置が#69の完全な裏返しになっていない。 ----------$ REVCOMP.DEF ( lines:49 ) -----------------------< cut here
遅いマシンで試したせいもありますが、やっぱり大きな範囲で比較すると少し時間 がかかりますね。でも、先日のおさわりもそうですが、やっぱり基本となる、2つ のファイルを行ったり来たりするのに比べて何倍速い、みたいな比較をしてみたい です。もしかしたら、行ったり来たりするバージョンの方がシンプルな分、それほど 速度差がでなかったりして。 機能的な面でいうと、ブロックモード不可、というのはキツイかも。 あと、> 改行を含んで比較していないのでなんとかしたい。これの関係だと思いますが、改行が増えたようなときに、こっちのファイルは段落の 最後の改行にカーソルがあって、もう一つのファイルは行頭というか、前行の行末の 改行にカーソルがある、というのはちょっとイヤです。
速度差を判定するには,カーソル往復版も作らなきゃいけないわけで,どう も気が進まなかった(^^;のですが,としきさんが忙しそうなので作ってみまし た。 ----------^ J23.DEF ( date:2005-04-24 time:18:59 ) ---------< cut here = t\j23 = by H_ear #if 0 テキストの逆順比較(カーソル往復cd比較版) #endif * mad for vz! 1 ^\ "" ?. &s :l ; ---- main loop ---- a-, cd[, #W (cd==0]) #s a+=r, #W #s a+=r, ?{ (a+2)>?{ >n >d >l } } :d &m(25) >z :n &m(24) :z ; ---- exit ---- &d #] . * [Variables] a #sの返り値の和 [Buffers] 未使用 [History] 2005/04/24 0.10 初版 [Notes] ----------$ J23.DEF ( lines:25 ) ---------------------------< cut here さすがに相当遅いです。 ところで,revcomp.def にはバグがありました。途中に改行だけ入れたよう なファイルで変な動作になりますので,以下のように修正します。 (r==i)?{ ;#.10 ↓ (r==i && aa==bb)?{ ;#.11 計測したところ,LX のような遅いマシンで 2.4:1,celeron-800MHz のノー トで 5:1くらいの速度差がありました。今考えているのは,ロングポインタを 使って,大きな範囲をスタックに読み込んで比較するというものです。これは かなり早くなると思います。> 機能的な面でいうと、ブロックモード不可、というのはキツイかも。贅沢だなぁ。まぁ,確かに #69は完全にメモリ上でやってるのでブロックモ ードに関係なしですが,そういうことであれば,速度は完全に諦めなければな らないでしょうね。> 改行が増えたようなときに、こっちのファイルは段落の> 最後の改行にカーソルがあって、もう一つのファイルは行頭というか、前行の行末の> 改行にカーソルがある、というのはちょっとイヤです。これは上の修正で直るのではないかと思います。 ただ,アレですね。 #69って,実行後のカーソル位置が相違点から一歩先に なってますよね。連続実行ができるようにということなんだろうと思うわけで すが,こういうのは逆だとどういうことになるのでしょう。一応それを再現す るようにカーソル反復横跳び版は作ってあるつもりですが,思惑と違ってたら 言ってください。
> 今考えているのは,ロングポインタを> 使って,大きな範囲をスタックに読み込んで比較するというものです。これは> かなり早くなると思います。これが何と,まるで速くなりませんでした。(^^; 仕方がないので,比較ループの部分を機械語にしてみたところ,劇的に速く なりました。結局,速度面のネックは繰り返し処理だったわけです。 計測したところ,celeron-800MHz のノートで 1MB/sec くらいになりました。 そのかわり,ブロックモード起動不可に加え,テキストスタックを初期化しま す。これは大きなバッファが必要ということで,仕方がないですね。 ----------^ REVCOMP.DEF ( date:2005-04-25 time:18:40 ) -----< cut here = revcomp.def v0.21 = by H_ear #if 0 テキストの逆順比較(スタックに取り込んで比較) #endif * mad for vz! 1 ^\ "" ?. (wa.5+wb.5)?{ &m("ブロックモードでは実行できません") . } &a("テキストスタックを初期化してもよろしいです") (r-1)?. &s 3(0) t=20000, ;取り込む単位(32000以下) :l ; ---- main loop ---- &> dz[=kz, di=kp-4, aa=kp..-1, dz], #W ;kp..-1:ブロックサイズ &> dz[=kz, si=kp-4, bb=kp..-1, dz], #W (aa<=bb)?i=aa, ?i=bb, ;比較回数は小さな方に合わせる bx=i, ax=kz, di=di-i, si=si-i, cx-, &01 ;機械語サブルーチンを実行 (cx==i && aa==bb)?{ 3(0) :b #s i=r, #W #s i+=r, #W (i+2)>?{ >q >d >l } &m("!Error") >z } &Ia(wa+126,aa-cx) #U #M #W &Ia(wa+126,bb-cx) #U #M #W :d &m(25) >z :q &m(24) :z ; ---- exit ---- 3(0) &d #] . 00: #b #M (wa..64)?{ &Is(wa+126,t) }?{ (wa..63>t || wa..63<0) ?{ &Is(wa+126,t) }?{ &Im(wa+126,0) } } #U mb2, #k #M 01: &i(3+$). "$(8E,D8,8A,00,3A,01,75,0A,4B,41,83,FB,00,74,03,E9,F0,FF,C3)" * [Variables] di,si address aa,bb block size i,bx,cx counter t text stack size ax kz segment address [Buffers] wa+126/wb+126 [4]Mark0 [Mnemonic] mov ds,ax A: mov al,[si+bx] cmp byte ptr al,[di+bx] jne Z dec bx inc cx cmp byte ptr bx,0 je Z jmp A Z: ret [History] 2005/04/21 0.10 初版 2005/04/22 0.11 一方の行頭まで一致する場合に終了時の位置合せを失敗していた 2005/04/25 0.20 ロングポインタ使用版 2005/04/25 0.21 比較ループを機械語に置き換え [Notes] ジョークのosawari.defに比べると,ちょっと真面目に作った。 Mark0はジャンプ時にVZによってセットされるので再セットが必要 [Todo] 済:改行を含んで比較していないのでなんとかしたい。(\l\n同一視になっている) 実行後のカーソル位置が#69の完全な裏返しになっていない。 ----------$ REVCOMP.DEF ( lines:76 ) -----------------------< cut here
> 速度差を判定するには,カーソル往復版も作らなきゃいけないわけで,どう> も気が進まなかった(^^;のですが,としきさんが忙しそうなので作ってみましどうもありがとうございます。 実は、マクロネタが少ないとなげいていためざらさんのために残しておいたの です。というのはウソですが、めざらさんに作ってもらえなければ、今夜か明日 ぐらいには自分で作っていたと思います。 ところで、このマクロ名の由来を教えていただけませんか?> さすがに相当遅いです。遅いですね。 メインマシンで試したところ、2KB/sくらいでしょうか。revcomp(旧版)で 20KB/sぐらい、機械語版では300KBのファイルがほぼ瞬時でした。> 贅沢だなぁ。まぁ,確かに #69は完全にメモリ上でやってるのでブロックモ> ードに関係なしですが,そういうことであれば,速度は完全に諦めなければなあきらめました。 自分のニーズを考えると、巨大なファイルの一部を遡り比較したい、ということが 割と多くて、今までは2窓を左右に並べて同じスクロールでやっていたのですが、 今後は比較範囲が大きいと予測されるとき以外は反復横跳び版を使うことが多く なりそうな気がしています。> これは上の修正で直るのではないかと思います。直ってました。> すが,こういうのは逆だとどういうことになるのでしょう。一応それを再現す> るようにカーソル反復横跳び版は作ってあるつもりですが,思惑と違ってたらこれは難しいですよね。 反復横跳び版と機械語版で同じ比較をしてみましたが、終了時のカーソル位置は 互いに微妙に違いますよね。今のところはどっちがいいとか悪いとか判断できない のですが、そのうち、どっちかになれてしまうと、もう片方に違和感を抱くように なるんだと思います。 以下は機械語版の話です。 ブロックモードなら現在のカーソル位置をマークして、ファイル先頭まで一致した とき以外は不一致検出箇所もマークして、その間をブロックするということはでき そうな気もしますが難しいのでしょうか。 テキストスタックがクリアされるという仕様は、私の使い方からすると問題はない のですが、この辺は人によるかもしれませんね。 あと、改行の比較のところは、今のところ問題になるような実例にあたっていない ので、実用性の面からはこのままでもいいかもしれません。
しまった,謀られたか…。 えーと,名前はですね,名無しのテスト版ってとこです。 テストマクロを作るマクロで自動的に連番で名前が付くのですが,使えそう ならマクロヘッダを書き換えるとディスク上のファイルもろともリネームする マクロで,常用の名前のあるマクロに昇格させます。したがって,これは捨て マクロ扱いということになります。 ブロックの再現というのは,やや厄介な問題です。再現させるのは別に厄介 ではありませんが,ブロック範囲が起動時のカーソル位置のどちら側にあるか によって範囲が異なってしまいます。 また,比較するテキストの表裏で併せて4通りのパターン,加えて行/文字 ブロックのどちら(矩形は無視するとして)であったのかの2通り。単に起動 位置を記憶するのとは違って,仕様によっては違和感をすごく強く感じる場合 があるでしょうね。 としき仕様ではどんな感じですか。範囲は無視して単に起動側の起動時のカ ーソル位置をブロックマーク位置(wa..55,wa..56)とするのであれば, 4バ イトのバッファを用意するだけで済むので簡単です。裏もなら8バイト。 &Le(pu,wa+110) ;puに保存 &Le(pu+4,wb+110) ;裏のブロックマーク位置 (2){ #W mb-, } ;;比較処理 #b &Le(wa+126,pu) #U ;表:マーク0に保存した値を転送してジャンプ #B mb2, ; #Bで相違発見位置に戻る #W #b &Le(wa+126,pu+4) #U #B mb2, ;裏 #W こんな感じでできると思いますのでやってみてください。あれー,ブロック モードの有無を保存して判定しなきゃいけないですね。これは面倒。> 今後は比較範囲が大きいと予測されるとき以外は反復横跳び版を使うことが多く> なりそうな気がしています。え〜〜っ 機械語まで無理して使ったんだけどなぁ…。 「はじめて読む8086」を引っ張り出してきて頑張ったのに,しくしく。> あと、改行の比較のところは、今のところ問題になるような実例にあたっていない> ので、実用性の面からはこのままでもいいかもしれません。ロングポインタ移動版では改行も含めて比較していますので,この問題は解 決しています。
> テストマクロを作るマクロで自動的に連番で名前が付くのですが,使えそうへぇ、そんなものを使われているのですか。> ブロックの再現というのは,やや厄介な問題です。再現させるのは別に厄介そんなに難しい問題とは思いませんでした。 気軽に要望を出してしまってごめんなさい。> え〜〜っ 機械語まで無理して使ったんだけどなぁ…。やっぱこれは、速度よりも使い勝手がものをいうような使い方が多いという事で。 せっかくいろいろと知恵を使っていただいたのに申し訳ない。> ロングポインタ移動版では改行も含めて比較していますので,この問題は解> 決しています。了解です。 この問題については、テストすらしていませんでした。 というより、テストできるようなデータを用意できないというか、そもそもそういう データに出会った事がないというか。
> へぇ、そんなものを使われているのですか。Yushiメニューでマクロ技術史に名を残した Yushi さんの tmacro.def です。 たいへん便利ですよ。あの番号になっているのは,作りかけで頓挫している マクロがそれだけあるってことなんですけどね。> そんなに難しい問題とは思いませんでした。いや,難しくはないんですけど,人によって考え方・仕様が異なってくるだ ろうな,と思うわけなんです。難しい,というのは,としきさんも使われてい る意味の「難しい」ですね。単に表テキストの起動位置からブロックするだけ でよいのなら簡単で,#99に書いた通りです。> やっぱこれは、速度よりも使い勝手がものをいうような使い方が多いという事で。わかりますよ。技術よりも仕様が大事というのは,使う側の人間の立場から 考えれば当然のことです。でも,その使い勝手って,ブロックモード再現のこ とであれば対応可能です。それからテキストスタックに関して言えば,あまり 大きな範囲を読み込むのではなく,数千バイト単位で読込みするのであれば, スタックもクリアせずに保全できます。速度はスタックに読み込む回数とあま り関係がないことが証明されていますから,反復版の使い勝手で高速化を図る ことが可能ですよ。(必死だな>おれ)
全然わかっていないので、以下、思いつきで物を言います。 現在、テキストスタックで比較しているようですが、たとえばこれを、&Eaで バッファを確保して、そこで比較、なんていうことはできるのでしょうか。 さて、実は今日、勤務中に一時的に手持ち無沙汰な状態が発生しました。 といって、ちょっと隔離状態だったため、ネットサーフィンで遊ぶというわけ にもいきませんでした。そこで、ちょっとそこいらにあったメモ用紙に、私が オリジナルで反復横跳び版を作るとなるとどうなるか、というもののスケッチ を描いてみました。いや、私の素晴らしい記憶力のおかげで、めざらさんの作 られたコードをほとんど何も覚えていなかったのは幸いでした。 #幸い? 以下、マクロコードのスケッチというか、ルーチンの断片です。 メモ用紙からの転記の際に、気がついた間違いは修正してありますが、新たな 間違いが紛れ込んでいるかもしれません。 = tmp = * m 79 ^\ "" ?. &s cp[, #W cp[, #W :a a=cd, #W b=cd, #W (a!=b)?{&m(相違あり) >e} #s a=r, #W #s b=r, #W (a!=b)?{&m(相違あり) >e} (a!=ファイル先頭)?{>a} :e スタック戻し * これを書いていたおかげで、優に30分はヒマをつぶせました。(笑) その後、約2時間の難行苦行が終わってから、模範解答というか、めざらさんの 反復横跳び版をもう一度じっくりと読ませてもらって、ループのところとか条件 分岐のところの巧妙さにあらためて感動しました。
> 現在、テキストスタックで比較しているようですが、たとえばこれを、&Eaで> バッファを確保して、そこで比較、なんていうことはできるのでしょうか。いやー,ここで &E?系の関数が出てくるなんてビックリです。(^^; 実際,そこまでやるかという感覚になります。…と言うのは,EMS でバッフ ァを確保しても,そこに転送するときはテキストバッファからということにな りますよね。それだったらテキストバッファ上で比較した方が無駄がないので はないでしょうか。変更する作業に使うわけじゃないですから。 そもそも,スタックに転送して比較した理由は,テキストバッファを扱う方 法を知らないからです。それができるのは…,最期のアクティブでは和生さん, YASAT さんくらい? 達人の ROM もいらっしゃったかもしれませんが,まぁ, ここに来てくださ るとも思えないので,無理かなぁ…。高度な質問に答えられなくてすみません。 実際なにも知らないんです。エディタがどのようにファイルを読み込んで, メモリ上のどこに置かれて,どのタイミングで vztemp.$$$ が作られて,それ らのファイルのどの部分がテキストバッファに読み込まれて,なんて事柄…。 そして,どのセグメントにファイルのどの部分が読み込まれて,それらがど んなふうにリンクしているかなんて事柄…。 今回は特に後ろから比較でしょ。 ところで,としき版では cp を保存していますが, cp を保存するなら直前 に #] を実行して cp がテキストバッファを指すようにしておく必要がありま す。それからテキストバッファは環境によって大きさが違うという以前に,最 大で 64KB の大きさしかありません。それ以上の大きさのファイルではセグメ ントをまたいだりするので,オフセット値を保存しても元の場所に戻れない可 能性が非常に高いということになります。 cp を保存・復帰して確実に戻れる のは行内とかそれに準ずる狭い範囲です。
> いやー,ここで &E?系の関数が出てくるなんてビックリです。(^^;全くわかっていないド素人のたわごとだと、聞き流してください。> ところで,としき版では cp を保存していますが, cp を保存するなら直前> に #] を実行して cp がテキストバッファを指すようにしておく必要がありまありゃ、そうなんですか。 やっぱり全くわかっていないという事の傍証にはなりそうですね。 ちなみにいうと、元々のメモ用紙では、一番最初のcpの、スタックへのpushとpopの 演算子を間違えていたりしたのでした。
> > いやー,ここで &E?系の関数が出てくるなんてビックリです。(^^;>> 全くわかっていないド素人のたわごとだと、聞き流してください。ニュアンスがうまく伝えられなかったようで補足します。言い訳っつーか。 「ここで」は「この場で」という意味で,「このケースで」という意味では ありません。この場は,「ローテクでもいい。自分で作ってみよう。」がコン セプトっていうか,小物マクロは VZ 町人文化の華って認識でやっているつも りなので,EMS メモリ操作関数なんて使ったこともないようなものが出てくる と,管理人がびびっちゃうわけなんです。(^_^; 多分…ですけど…,例えばディスク上のファイル同士を比較するような場合 であれば,ハンドルでオープンする場合のバッファとして &E?()関数で確保し たメモリを使うことで,ユーザが使用するバッファを汚さずにあるいは初期化 することなく処理を行えるのだと思います。 すでにオープンされているファイルで,もしかすると変更が加えられている かもしれないテキストを比較するという場合は,結局メモリ間の転送が発生す るので,それなら元のメモリ同士を比較すれば済むことではないかと思ったり するわけです。ただ,その方法は知りませんが…。(^^;
> ニュアンスがうまく伝えられなかったようで補足します。言い訳っつーか。> 「ここで」は「この場で」という意味で,「このケースで」という意味ではあ、そういう事でしたか。了解しました。 ただ、いずれにしろ、そういうモノを使うにはどうする、みたいなことが私には わかっていないというのはありまして。
> 確かに、カーソルバンバン飛ばし以外は「もはやマクロでない」ということに> なりそうですね。#69 作戦も、おっしゃるとおり「カーソル位置から」の条件がそこまでは言い切れないですが,後ろから比較しなければならないケースを 想像しきれないので,どうすれば最も適切な方法になるのか解らないのです。 末尾の方だけ違いがあるなら素直に先頭から比較すればよいし,> 斬新なアイディアとしては、一度2つの比較ファイルの中身を全部ひっくり返> してしまっておく、というもの。げ、野蛮。rev という unix-like tool で行の裏返し作戦はわたしも考えたのですが,全部裏返しても無駄だし,行単位で 裏返すとしても文字単位・バイト単位でやり方が異なること,相違点を見つけ ても元ファイルの桁位置を合わせるのが面倒だなぁとか考えると,素直にやっ た方がよさそうに思いました。> s/a/b/ とか s/a/b/3> に該当するVzマクロについてはアルゴリズム・アイディア浮かびますか?フラグの3って何ですか? 全然わからないんですけど…。(^^; ご説明をお願いします。> うん、つまらない話になってしまった。汎用的だからつまらないということはなくて,結構重要な話ですね。 タブ区切りデータというのは,なかなか扱いやすいし,他のアプリから複写 する場合,「表」はタブ区切りになるのが普通のような気がします。 最初のタブのある地点を処理するなら,次のような話でしたっけ? s/^\([^\t]+\)\t/\1》<TAB>/
> 裏返し作戦はわたしも考えたのですが,全部裏返しても無駄だし,(後略)僕も賛成です。無理やりrevとtacの使い道を探してる感あり。 ↓ですが(こういう言い方もなんですが)、↑とともに、あまり真面目に考え ないでくださいね。>> s/a/b/ とか s/a/b/3> フラグの3って何ですか?serow 版にはないのですが、s/a/b/ は、s/a/b/1 の意味ですよね。 つまり行 内の最初のヒットだけ置換する。そういう意味では、Vzの置換は常にグローバ ルです。s/a/b/3 だと、3番目のヒットだけ置換するんですよ(純粋なsedだと)。> 最初のタブのある地点を処理するなら,次のような話でしたっけ?> s/^\([^\t]+\)\t/\1》<TAB>/そうです。ただ行頭指定しなくても s/\t/》<TAB>/ でいいって話です(グローバルフラグがないので、最初のヒットだけ置換する ので)。 いや、この話は無意味。なんか機械的なの、「こんなマクロが」というネタが あったんですけどねぇ…。メモっとくべきだなぁ…。5つくらいあったんですが…。 sedの機械的なスクリプトを書いていたときに…。
> serow 版にはないのですが、s/a/b/ は、s/a/b/1 の意味ですよね。 つまり行> 内の最初のヒットだけ置換する。そういう意味では、Vzの置換は常にグローバ> ルです。s/a/b/3 だと、3番目のヒットだけ置換するんですよ(純粋なsedだと)。へぇー,便利ですね。 今, 一番使いやすい sed って何版なんですか? LX メインってこともあっ てセロー版をずっと愛用しているのですが, DOS 窓だったら DOS Extention 版(って言うのかな)だって使えるでしょうから,もっと楽ができそうですね。> いや、この話は無意味。なんか機械的なの、「こんなマクロが」というネタが> あったんですけどねぇ…。メモっとくべきだなぁ…。5つくらいあったんですが…。いつでもいいですよ。気が向いたらメモ代わりにここに書いてください。 普段はいつも資料作りをしてますので,マクロネタに飢えてるんです。
> へぇー,便利ですね。はまる場面は少ないような気がしますけど、でも「最初だけ」についての、な んでデフォでグローバルでないの? という疑問を晴らしてくれたとは言えなく もない、ぐらいでしょうか。> 今, 一番使いやすい sed って何版なんですか? LX メインってこともあっ> てセロー版をずっと愛用しているのですが, DOS 窓だったら DOS Extention> 版(って言うのかな)だって使えるでしょうから,もっと楽ができそうですね。あの例は、そう見えるかもしれませんね。で、ドス窓限定(LXの純ドス駄目) だと、Bruce. さんが割と最近、移植・合成してくれた mbsed, onigsed があり ます。前者は GNU 最新版の移植、後者は oniguruma って Ruby 関連の正規表現 ライブラー(ほぼ Perl 相当)を組み込んだ最強版です。もちろん、両者とも、 日本語対応してあります。 http://www.kt.rim.or.jp/%7Ekbk/sed/index.html あれ? mbsedのリンクが切れてるみたい…。使うなら、onigsedをどうぞ、とい うことかしら。> いつでもいいですよ。気が向いたらメモ代わりにここに書いてください。> 普段はいつも資料作りをしてますので,マクロネタに飢えてるんです。きゃ、嬉しい。 でも思い出せない…。 ま、大したものじゃなかったんですね (忘却に値する程度の超小物)。
実は数年前に sed のことで FGALTS に相談に行った折りに Bruce.さんに mbsed(当時は sedm と呼ばれていた)を紹介されて使わせてもらったところ, メモリ不足エラーが出まくりで,結局使えなかったということがあったのです。 使えなかったマシンというのが職場の NEC-98の Win95の DOS 窓で,その代 わりセロー版 sed が元気に働いてくれました。 サイズも小さかったし, DOS 汎用だったので,もっぱら人の仕事の手助けでしたが,環境を選ばずどこでも 問題なく使えてました。動作テストも LX でできたので,なにかあったらすぐ に対応できたんですね。 今度は素直に onigsed が動いてくれるといいなぁ。