bashスクリプトで正規表現
前書き
僕が正規表現をよく使うのは、vimで文字列の検索や置換をするときですが、たまにシェルスクリプトの中で使いたくなることがあります。そういう時普通はperlで書くのでしょうが、あいにく僕はperlがつかえない(orz)ので、毎回edやらgrepやらsedやらawkやらを調べて場当たり的に解決しています。で、この前、後輩に質問されて「う、こんな簡単なことなのにどうやったらいいのか分らないなんて!」とショックを受けたことがあったので、調査結果をメモっておきます。
問題
データを行毎に記録したテキストファイル(例:data.txt)がある。そのテキストファイルを1行ずつ読み取って、コマンドを実行したい。ただし、#で始まる行や空行は無視したい。
解答
exprコマンドは、正規表現を解釈する(!)ので、それを使う。
#!/bin/sh TARGET_FILE="data.txt" while read LINE do if expr "$LINE" : "#" > /dev/null || [ -z "$LINE" ] then continue else echo "$LINE" fi done < $TARGET_FILE
注意点は、exprの標準出力を/dev/nullに捨てることと、正規表現の先頭に暗黙のうちに"^"(行頭)が付加されること。
以下実行例:
[lucy@fedora7 regexp]$ cat data.txt one #two four five six# se #ven ten [lucy@fedora7 regexp]$ ./regexp.sh one four five six# se #ven ten
まとめ
exprで正規表現を扱えるとは知りませんでした。expr string : regexp もしくは expr match string regexp でもよいみたいです。標準出力にはマッチした文字数がでるみたいです。また、\( \)で囲ってある部分があれば、そこの文字列がでるそうな。詳細はこの辺で。
でもbashのfor文だと、行区切りではなくて、空白区切りでループされてしまうので、1行内にブランクがある場合はどうしたらいいんでしょね。これまたFAQの類だと思うんですが、また分ったら書きます。
というわけで、
while read LINE do : done < $TARGET_FILE
構文(?)で修正したプログラムを載せてみました。
| 固定リンク
この記事へのコメントは終了しました。


コメント