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

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

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

参照用 記事

headコマンドを、Emacsのgrepモードで使う

かなりたくさんのファイルがあって、それらの先頭の数行を眺めたい -- そんなときは、headコマンドとlessコマンドを繋げばいいでしょう; head * | less 。

眺めるだけじゃなくて編集もしたいときは、エディタ内からheadコマンドを実行したいですね。僕はEmacsを使っているので、Emacs内からheadしたいわけです。

話を具体的にするために、次の状況を想定します。

  • 僕(檜山)のはてなダイアリーの記事が hatena-*.txt というファイルに入っている。
  • それらの記事の先頭部分を列挙したい。
  • 先頭部分を眺めて、必要があれば編集をしたい。

サンプルには4つのファイルしかありません(↓)が、実際にはたくさんのファイルを相手にしてます。


$ ls hatena-*.txt
hatena-2016-03-23.txt hatena-2016-03-26.txt
hatena-2016-03-25.txt hatena-2016-03-30.txt

$

これから使うEmacsのM-x grepの機能と使い方については次の記事を参照してください。

M-x grepは、grepに限らずどんなコマンでも実行できます。M-x grep C-a C-k の後に任意のコマンドラインを入力すればいいのです。コマンドとして、head -n 5 hatena-*.txt とか入力すれば、headの出力がgrepバッファ(バッファ名*grep*)に取り込まれます。

しかし、headの出力はgrepの出力とフォーマットが違うので、C-x ` (next-error)などgrepモードの機能が動きません。headの出力をsedで加工すればいいでしょう。

  • head -n 5 head -n 5 hatena-*.txt | sed -e "s/^==> \(.*\) <==$/\1:1:/"

毎回このパイプラインを手で書くのは大変なので、シェルスクリプト、またはバッチファイルにしておきます(コマンドライン引数がないときと、単一ファイルが引数となる場合も考慮してます)。

#!/bin/sh
if [ "$1" = "" ]; then exit 1; fi
head -n 5 -v  $* | sed -e "s/^==> \(.*\) <==$/\1:1:/"
@echo off
if "%1" == "" exit /b 1
head -n 5 -v  %1 | sed -e "s/^==> \(.*\) <==$/\1:1:/"

このスクリプトをghead(grep風head)という名前で呼び出せるとして、M-x grep C-a C-k ghead hatena-*.txt でgrepバッファが使えるようになります。grepバッファ内でファイル群の先頭部分を読んでいって、必要があれば当該ファイルを開いて編集ができます。