On Sat, 30 Aug 2008 14:35:58 +0900
Bunta <hi9t-ooy@...-net.or.jp> さんwrote:
>
> 藤岡さん
>
> 全体として、僕が不具合に遭遇してから考えて調べたことを遡ることになりま
> す。ごゆっくり、どうぞ。
>
> > なぜそんなことができるのかを説明して欲しいのです。
> > ステップを追って、動作を言葉で説明して欲しい。
>
> 僕なんかの言葉より、パイソンのデバッガが出している過程を1つ1つ追った
> ほうが正確だと思います。けれど、頑張ってみます。
ありがとうございます。おかげさまでよくわかりました^^)v sedで複数行処理
は経験がなかったので助かりました。後、ホールドスペースの使い方を理解すれ
ば、sedのスペシャリストになれそう^^;)
理解の過程を示すために、多少補足を入れながら書きます。
> 例はまず単純なほうを使いますね。
> ------- test1.sed -------
> # all seds, OK except gsed3 (GNU3 + mb1.07)
> $!N #(0)
> /^aaa\n---$/{ #(1)
> s/\n/\ #(2) s/\n/\n\n/ の意味。(5)のため空行追加。
> \ #
> / #
> P #(3) 「aaa」出力
→ 「aaa\n」出力ですね。
> s/^aaa\n// #(4) これにより PS は「\n---」となる
→「\n---\n」となる
> }
> P #(5) 「\n」出力
→ パターンスペース先頭の「\n」出力
> D #(6)
→ パターンスペース先頭の「\n」削除
→ パターンスペースには「---\n」が残っている。
> さて、
>
> C:\>gsed3 --version
> GNU sed version 3.02 + multi-byte extension 1.07
>
> 以外では、ここまででは問題が出ません。 そしてgsed3に僕はこだわりがない
> ので(Perl-like regexが使えませんので)、よいのです。また、上の「aaa\n---」
> は、 あくまでonigsedのバグ出し(恐い言葉、ごめんなさい)のために考案した
> テストです。
onigsedが必要な目的を含めて理解しました(^^)
> ではどういう場合にonigsedで問題が出るのか。デリミタの前が「aaa」でなく、
> もう少し汎用的に記述した場合、つまり「空行でないなら」と記述した場合です。
> これは
>
> aaa
> でなく
> [^\n][\n^]*
> とsedのBREでは記述されると思います。([^\n]*と略記して同じだと思いますが)
「[^\n][^\n]*」と「[^\n]*」は当然ながら意味が違います。後者だと空のパ
ターンにもマッチしてしまいますから。
> すると、スクリプトはこうなります。
>
> ------- test2.sed -------
> $!N
> /^[^\n][^\n]*\n---$/{
> s/\n/\
> \
> /
> P
> s/^[^\n][^\n]*\n// #(*)
> }
> P
> D
> -------------------------
結論として、onigsedでは、次のようにすれば意図どおり動作するようになり
ます。当たり前といえば当たり前なのですが・・・
^-----
# デリミタ"---"の前が改行でないなら改行挿入
$!N
/^[a-z][a-z]*\n---$/{
s/\n/\
\
/
P
s/^[a-z][a-z]*\n//
}
P
D
-----$
なぜこれを試したのかは「^aaa\n---$」がマッチして「^[^\n][^\n]*\n---$」
がマッチしないからですね。
もちろん、これでマッチしたからどうこう言っても仕方がないのですけどね。
もう一つ試したのは、もっと広い範囲でマッチするように「^..*\n---$」です
けど、これもマッチしませんでした。「.」は「[^\n]」の意味ですから当然かも
しれませんね。
藤岡 和夫
kazuf@...
日曜プログラマのひとりごと http://homepage1.nifty.com/kazuf/renewal.html