とっておきの「夜食」教えて下さい

現在、非常に多数のドキュメントの整形を LaTeXを使って自動的に行っています。
問題となっている処理のエッセンスを抜き出すと次のようなもので、テンプレートファイル中の __PATTERN__ という文字列を、その都度指定する文字列($string)に置換した後にplatexでコンパイルする、という流れです。

----------
#!/bin/bash
sed "s/__PATTERN__/$string/" < template.tex > document.tex
platex document.tex
----------

問題は、$string に '_'(アンダーバー)が含まれるケースで、platexのコンパイルでエラーが発生します。
これを回避するには、'_' を '\_' に置換する必要がありますが、上記処理の前に、$string 中の '_' を '\_' に置換する処理を加えても、上記処理の段階で '\' が消えてしまいます。

肝は sed でのエスケープのやり方だと思うのですが、どうにもうまく行きませんので、お知恵を拝借できればと思います。

なお、tex ファイル中、__PATTERN__ は、他のコマンドの引数内で使用されているため、\verb+ + で囲むという手段も使えません。

A 回答 (2件)

""中なら \ は \\ とクォートしないとダメですね.


ちなみに「$string 中の '_' を '\_' に置換する」のはどんな処理ですか?

この回答への補足

ありがとうございます。自己解決しました。

> ""中なら \ は \\ とクォートしないとダメですね.

とのご回答のとおり、最後の置換で \ を一つ残すためには、事前に $string 中の '_' を '\\_' に置換する必要があり、このためには、

sed 's/_/\\\\\\\\_/g'`

と、バックスラッシュを8個並べれば良いようです。

4個でいいと思っていてうまくいかないので質問したのですが、これで解決です。どうして8個必要になるのかがイマイチ理解できていませんが。

補足日時:2008/09/26 00:45
    • good
    • 2

>どうして8個必要になるのか


エスケープを処理するステップが何回もあるからです。

sed "s/__PATTERN__/$string/"

なので、$string に8個の '\' があったとすると、

・sed に渡されるのは4個の '\' になります。(1回目)
・さらに置換ルーチンに渡されるときに2個になります。(2回目)
・置換ルーチンがその2個の'\' を1個の'\'と解釈します。(3回目)

→出力されるのは1つ

というわけです。
    • good
    • 3

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報