ochalog

RubyとMediaWikiとIRCが好き。

grep と sed で文字列置換

シェルスクリプトで、ファイルの中身を対象として、JavaScript とか Ruby のようにある文字列を取り出して置換するということがしたかったので、試行錯誤してみた。最終的に

egrep -m 1 -o "拡張正規表現" ファイル | sed -E -e "s/拡張正規表現/置換文字列/"

ただし、Linux では sed拡張正規表現使用オプションは -r になるらしい(「sed/grepコマンドの正規表現 - Miuran Business Systems」より)。「MacWiki - sed#拡張正規表現を使うには」によると、-E オプションは Free BSD 由来の sed でのみ使えるらしい。

grep のオプションで、今回調べて初めて知ったのが以下のもの。Man page of GREP に載っていた(だいぶ古いが)。

-m NUM, --max-count=NUM
マッチした行数が NUM に達したら、ファイルの読み込みを中止する。
-o, --only-matching
マッチする行のマッチした部分だけを表示する。

実例

Hiki2MediaWiki for SRW Wiki の更新作業を楽にするために、バージョン番号を含むディレクトリを作ろうとした。

ファイル群の中に更新履歴(changelog.html)があり、以下のような内容が含まれている。

<h3>2013-03-10(Ver. 2.2.3)</h3><h3>2013-03-07(Ver. 2.2.2)</h3><h3>2013-02-27(Ver. 2.2.1)</h3>

バージョン番号は他の部分には含まれておらず、降順で並んでいる。

この状態で以下のシェルスクリプトを実行すると、../hiki2mw-2.2.3/ というディレクトリが作成される。

#!/bin/sh
 
pack_dir=$(egrep -m 1 -o "Ver\. [.0-9]+" changelog.html | sed -e "s/Ver\. /..\/hiki2mw-/")
pack_dir=${pack_dir}/
 
mkdir $pack_dir
echo "Made directory $pack_dir"

この場合は sed拡張正規表現を使う必要がなかったので、-E オプションは外しておいた。