このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

grepコマンドとEmacs grepモードって、やっぱり便利だよな

grepコマンド、それとEmacsのM-x grepgrepモードって、かなり便利ですよ。プログラミング以外の用途でもいろいろ使えます。

WindowsでもUnix系OSでもほとんど同じですが、差がある部分は括弧内に示します。

例題の説明

僕は、はてなダイアリーをブラウザから直接書くことはあまりなくて、前もってテキストエディタで書いたものを貼り付けています(これは事実)。各分類カテゴリごとにファイルを分けて、hatena-nitijo.txt, hatena-zakki.txt, hatena-memo.txtとなっているとしましょう(事実じゃない、あまり整理してない ^^;)。

はてな記法では、行頭に「*」があるとエントリータイトルなので、次のコマンドで全エントリータイトルを列挙できます(Unix系では、ダブルクォートの代わりにシングルクォートを使用してください)。


grep "^\*" hatena-*.txt

grepコマンドの場合は星印「*」をエスケープする(「\」を付ける)必要はないのですが、正規表現一般の構文としてはエスケープすべきですね。

さて、出力はこんな感じ。


hatena-memo.txt:*t*[雑記/備忘][檜山用メモ]リネームとサブタイプと置換原則
hatena-memo.txt:*t*[雑記/備忘][檜山用メモ]積と指数の随伴に関する練習問題
hatena-nitijo.txt:*t*[日常]考えない勇者
hatena-nitijo.txt:*t*[日常]聞いてしまったTV番組企画
... (省略)

-nオプションで行番号を付ける


grep -n "^\*" hatena-*.txt

と、-nオプションを付ければ、タイトルが出現した行の番号も表示されます。


hatena-memo.txt:2:*t*[雑記/備忘][檜山用メモ]リネームとサブタイプと置換原則
hatena-memo.txt:364:*t*[雑記/備忘][檜山用メモ]積と指数の随伴に関する練習問題
hatena-nitijo.txt:1:*t*[日常]考えない勇者
hatena-nitijo.txt:12:*t*[日常]聞いてしまったTV番組企画
... (省略)

ファイル名と行番号が付いた出力は、いろいろな場面で大変有効に使えます。

ファイル指定にnul(/dev/null)を含ませておこう

ちょっとした落とし穴があります。

例えば、hatena-memo.txt内に1つしかエントリーがないとき、*1hatena-memo.txtだけをコマンドラインに指定したら、grepの出力はどうなるでしょうか? こうなります。


2:*t*[雑記/備忘][檜山用メモ]リネームとサブタイプと置換原則
364:*t*[雑記/備忘][檜山用メモ]積と指数の随伴に関する練習問題

ファイル名が省略されてしまうのです。hatena-*.txt のようにワイルドカードを使っていても、マッチするファイルがhatena-memo.txtだけなら同じ出力になります。

手動でgrepを起動しているならたいした問題ではないのですが、バッチファイル(シェルスクリプト)内でgrepを使っているときは変なことになるかもしれません。


grep -n "^\*" nul hatena-*.txt > hatena-entries.grep

のように、nul(/dev/null)をファイル指定に入れておくといいでしょう。

Emacsからgrepコマンドを使う

Emacs内からgrepするには、M-x grepです。上で述べた注意事項は、Emacsが気を使ってくれるので安心です(パターン先頭が「-」である事態も想定して、-eオプションも付けてくれます)。

キーボードから "^\*" hatena-*.txt を入力すると、コマンドラインから


grep -n -e "^\*" hatena-*.txt NUL
としたのと同じになります。最後のNUL(/dev/null)はEmacsが付けてくれます。

Emacsgrepモードを使う

便利なのはここからです。grepの出力が取り込まれたバッファは自動的にgrepモードになります。ほらっ、きれいにカラーリングされているでしょ。カラーリングだけじゃないですよ、*grep*バッファに移ってのn(next-error-no-select)とp(previous-error-no-select)がすごーく便利(下の画面参照)。エントリータイトルと第1段落をザッとブラウズするのに最適。


原寸大

タイトルに対応する本文(hatena-*.txt)内の位置にカーソル移動するには、RETまたはC-c C-c(compile-goto-error)です。本文に移ってからも、C-x `(next-error)で次から次へとエントリーをブラウズできます。M-g nでもC-x `と同じ。これらと対になるコマンドはM-g p(previous-error)です。

ファイルを自動的にgrepモードで見る

僕は、コマンドラインからのgrep出力をファイルに取っておくことがあります。


grep -n "^\*" nul hatena-*.txt > hatena-entries.grep

hatena-entries.grepEmacsに読み込みます。そして、M-x grep-modeとすれば、上記と同じ状態になります。

.grep拡張子(なんでもいいけど)から自動的にgrepモードにするには、.emacs内に次のように書いておきましょう。


(add-to-list 'auto-mode-alist
(cons "\\.grep$" 'grep-mode))

*1:「1つしかエントリーがない」って、なんで書いたのだろう? 今となっては意味不明。たぶん、「1つしかファイルがない」と混乱して書いてしまったのだと思います。