技術メモ

後で同じ状況が起こった時に思い出せるように技術的なちょっとしたことをメモする。ベストな解ではない。



sedでクオーテーションマークの挙動と正規表現でハマった


LaTeXソースコードの全ての”式n“(nは整数)を”式(n)”と置換したく(具体的には式1→式(1)のような感じ)、sedコマンドを使うことにした。
ただ数字を括弧で挟むだけなのですぐに出来ると思ったが、少しハマったのでメモを残す。
実行環境はWSL(ubuntu)で行った。sedコマンドは環境によって挙動が変わる可能性があるので注意してほしい。(いきなり実行せずにファイルのバックアップを取ってから実行したほうが良い。)





 

やりたいこと

文章中の”式1→式(1)”のように”式n→式(n)”と、数字を括弧で挟みたい。
実際のTeXコードでは、式\ref{equation1}式(\ref{equation1})と置換をする(equation1のところには任意のラベルが入る)。
単純であるが、意外と面倒くさい。





 

やったこと

sed -e “s/式\\ref\{\([^\}]+\)\}/式(\\ref\{\1\})/g” src.tex>out.tex

src.texを置換してout.texに出力する想定である。
これが意図していることは「式\ref{‘}’を含まない任意の文字列}」を「式(\ref{‘}’を含まない任意の文字列})」に置換するということである。
‘}’を含まないという条件によって{}に囲まれた範囲のみの文字列をマッチさせることができる。
しかし、このコマンドは意図したとおりに動かなかった
理由は以下である。

  1. sedでは{}はメタ文字でないためエスケープシーケンス(\)をつける必要がない。(\{→{, \}→})
  2. sedの正規表現の’+'(1回以上の繰り返し)は’\+’とする必要がある。(+→\+)
  3. クォーテーションマーク(‘)、ダブルクオーテーションマーク(“)でのエスケープシーケンスのシェルでの展開のされ方が異なる。(どう異なるかは分からないが、意味が異なるので注意)(‘←→”)

この3つを直すことで意図した置換が出来た。





 

結果

sed -e ‘s/式\\ref{\([^}]\+\)}/式(\\ref{\1})/g’ src.tex>out.tex

とすることで、式\ref{‘}’を含まない任意の文字列}」を「式(\ref{‘}’を含まない任意の文字列})」に置換できた。
正規表現の書き方がsedでは微妙に違うので注意しないといけないことを学んだ。





 


タグ:
投稿日: 2018年2月19日





コメントを残す

回答をお約束することは出来ませんので予めご了承ください。
コメントは承認されると表示されるようになります。
コメントを送信する前に「私はロボットではありません」にチェックを入れて下さい。