2007年10月07日(日曜日)

パイプライン処理とsedで解決 [ UNIX ]

いろいろ調べた結果、複数のコマンドをパイプで繋げば出来そう。もしかしたら、bashに正規表現の置換が組み込まれているかもだが。もっとも、シンプルなプログラムを組み合わせて複雑な作業をさせるってのが、UNIXの元々の思想だから、以下の方法は案外と正統派かもしれない。

echo で変数を標準出力に出して、これをパイプで sed (stream editor) に繋ぐ。sed は正規表現(多分)が使える。 sed s/文字列1/文字列2/ とすれば文字列1の部分をサーチして文字列2に置換する。今回の場合、サーチの対象はファイルではなくパイプラインでやってきた標準入力。文字列1は拡張子を除いた部分にマッチするようにして、文字列2は空にする。こうすると、拡張子以外が空の文字列に置換され、結果は拡張子のみとなる。拡張子以外にマッチさせるには、正規表現を用いて、 ^.*\. とする。「^」は行頭にマッチ、「.」は任意の1文字にマッチ、「*」は0個以上の任意の文字列にマッチ、「\.」はドット(ピリオド)にマッチする。sed では最長マッチが採用されているらしいので、これで途中にドットがあるファイル名についても最後のドットまでがマッチすることになる。これを空文字に置換すれば、拡張子のみが抽出される。結局、
echo ファイル名 | sed -e 's/^.*\.//'
とすれば、ファイル名から拡張子の部分を取り出すことができる。この文をバッククォートで囲めば、コマンドとして実行され、その結果(拡張子)が帰ってくるので、それを mp と比較すればよい。

ということで、拡張子チェックの部分を
if [ `echo $infile | sed -e 's/^.*\.//'` != 'mp' ]
に取り替えた。

投稿者 sukarabe : 15:11 | この記事の固定URI | コメント (0) | トラックバック (0)

メタポスト・プレビュー用のシェルスクリプト [ MetaPost, UNIX, プログラミング ]

前回は tsch で叩き台を作ったが、これからはbashでスクリプトを書くことにした。基本的に、TeXShopから呼び出す使い方がほとんどなので、それを想定して作成。Pathは通っているので省略し、エラー処理ではないが、ちょっとだけ if ... then ... else ... fi 構文を使ってみた。if文はCに似ているが、if (条件式) ではなく、if (条件文) であることに注意! 条件文を実行したステータスで判断するらしい。[.....] で括った部分は条件式に見えるが、実は testコマンドで実行させた結果を返しているということらしいのである。

苦労(?)したのは、ファイル名から拡張子を取り除くとか言った、文字列処理の部分。こういう所は、言語によって書き方が様々。bashの場合は、${string%hoge} と書けば、後方から最短マッチで$stringからhogeの部分を除去する。あ!しまった。この書き方じゃまずいことに、たった今気付いた。これでは、ファイル名の途中に「.mp」が含まれていると、そこを除去してしまう。まあ、そんなファイル名(sample.mpost とか)は使わないだろうが、それでもバグには違いない。末尾の「.mp」に限って除去するにはどうすれば良いのだろうか。

#!/bin/bash
#
# 使い方(Usage)
# mp2pdf foo.mp
#
# 0) 拡張子が mp でなければ何もせずに終了する。
# 1) 拡張子が mp のときは、jmpost を起動する。
#    jmpost により foo.1, foo.2, etc. の画像(PostScript file)が作られる。
# 2) foo.0 が存在すれば、それをプレビューするために、
#    foo.ps に複製し、ps2pdfにより、foo.pdf を作る。

# 必要ならば、パスを通す。
# ファイル名の設定 # infile=foo.mp のとき、basename=foo, fig_zero=foo.0, fig_ps=foo.ps # infile="$1" basename=${infile%.mp} # infile の末尾に .mp があれば、それを除去した文字列になる(バグあり) fig_zero="$basename.0" fig_ps="$basename.ps" fig_pdf="$basename.pdf"
if [ $basename = $infile ] ## 一致するのは、ファイル名が .mp で終わらないとき then echo "拡張子が mp ではありません" exit fi
echo "MetaPost(日本語版) を起動します" jmpost $infile if [ -f $fig_zero ]; then ## foo.0 が存在する場合 echo "$fig_zero からプレビュー画像 $fig_pdf を作成します" cp $fig_zero $fig_ps pstopdf $fig_ps else echo "プレビュー画像はありません" fi

投稿者 sukarabe : 12:35 | この記事の固定URI | コメント (5) | トラックバック (0)

2007年10月04日(木曜日)

シェル・プログラムの勉強 [ UNIX ]

UNIX シェルスクリプト辞典

TeXShopからMetaPostを使うスクリプトを書こうという目的で、UNIXのShellプログラムの勉強をしてみようと思った。先日叩き台は作ったのだが、ファイルが存在しないときの処理など、ある程度きちんとしたものを作りたいので。

ネットにも情報は転がっているのだが、通勤時間を利用したいのと、やはり紙で読む方が好きなので、とりあえず簡単な入門書を求めて本屋に行ってみた。

最初の問題は、bashとcsh(もしくはtcsh)のどっちにするかということ。これがなかなか悩ましい。バークレイ系のC Shellもよさげに思えたが、GNUのデフォルトはbashだしなあ。ということで、内容も考えて、「UNIX シェルスクリプト辞典」なる本を購入。最初に簡単な概要があり、次にシェル・コマンドの使い方、最後に目的別のレシピ本という感じの3部構成。老人には文字がちと小さいぞ、ということを除けば、まずまずの内容。もっともレシピは、ワタシには縁のなさそうな高級な例が多いのだが。

ネット上にも、参考となるページがいろいろある。さしあたりワタシのような初心者には、BASH Programming - Introduction HOW-TO (日本語版) あたりから始めるのが良さそう。ざっと見た限りでは、CやPascalによく似た感じで書けば良いようだ。これならワタシにも出来そうである。ちょっと頑張るですよ。

投稿者 sukarabe : 23:55 | この記事の固定URI | コメント (2) | トラックバック (1)