いまさらコマンドラインの便利さを主張してみる
尾藤正人(a.k.a BTO)です
僕の偏見かもしれませんが、Webプログラマの方の多くはコマンドラインをうまく活用できてないように感じます。
コマンドラインを使いこなすには最初にある程度の勉強が必要で、その敷居の高さのせいであまり便利さが感じられないのかも。
そこで、今更ながらコマンドラインの便利さを高らかに主張してみます。
ワイルドカード
ワイルドカードという特殊文字を使うと特定パターンのファイル名を簡単にしてできます。
これは知ってる人も多いので、詳細は割愛。
ワイルドカードでうまくいかない場合は後述するfindコマンドを使います。
zshのワイルドカード
zshのワイルドカードを使うと、ちょっとしたfindコマンドのようなファイル名のマッチができます。
簡単に紹介すると次のようなことができます。
echo **/foo # 再帰的に 'foo' にマッチ echo *(/) # ディレクトリだけマッチ echo *(.) # 標準ファイルだけマッチ echo *(@) # シンボリックリンクにだけマッチ
パイプ処理
僕がコマンドラインが好きな最大の理由がパイプ処理です。
パイプ処理の仕組みは非常に単純で、入力と出力をパイプのようにどんどん加工していくだけです。
パイプ処理は組み合わせて簡単に複雑なことができる
パイプ処理を使うと様々なコマンドラインツールを組み合わせて処理することができます。
パイプ処理のおかげで、UNIXのツールは一つ一つが単純な処理だけ行えばよくなり、組み合わせることで複雑な処理がいとも簡単に行えるようになります。
パイプ処理を使って簡単な処理を組み合わせて複雑な処理を実現するのはプログラミングに似てます。
プログラミングも一つ一つの処理は単純ですが、組み合わせることで複雑な処理が実現できます。
違いはパイプ処理の方が早く、短く目的を実現できるところでしょうか。
パイプ処理の例
例えば、subversionで新規ファイルを全てaddするとかは、こんな感じでできます。
svn status|grep '^?'|awk '{print $2}'|xargs svn add
これぐらいの機能ならGUIアプリでも提供されてるでしょうが、例えば画像ファイルだけ追加したい場合はどうでしょうか。
GUIアプリの場合はアプリ自体に機能がなければお手上げですが、コマンドラインならいとも簡単に実現できます。
svn status|grep '^?'|grep '¥.gif$'|awk '{print $2}'|xargs svn add
パイプ処理で活用したい文字列処理ツール
UNIXにはパイプ処理を活用するツールがいろいろあります。
特に、sed, awk, perl, rubyのようなパイプ処理で使いやすい文字列処理を提供しているツールを活用するのがいいでしょう。
perlやrubyのような汎用的な言語を一つマスターしておくと、応用範囲が格段に広がります。
個人的にはsed, awkをよく使い、少し複雑な処理にはrubyを使ってます。
findで対象範囲を絞り込み、xargsで効率よく実行する
findとxargsを使うとコマンドラインの活用範囲が一気に広がります。
findを使って処理対象のファイルの絞り込みが行え、xargsを使うことでコマンドを効率よく実行することができます。
提供されているコマンドがどんなに単純な処理しか行えなくても、findとxargsを組み合わせることによっていとも簡単に複雑な処理が行えるようになります。
xargsに関してはディノのhnwさんが大変素晴らしい記事書いてくれてるので、そちらを参考していただければと思います。
ヒストリ
コマンドラインを活用する上で、非常に重要なのがヒストリです。
実行したコマンドがどんどんたまっていくヒストリは自分自身の財産です。
ヒストリにたまっているコマンドに素早くアクセスすることで、目的の処理を素早く行うことができるようになります。
ヒストリを使いこなす上で重要なのが、素早く目的のコマンドにアクセスすることです。
僕がよく使ってるヒストリ検索方法を紹介してみます。
使っているシェルはzshです。
zshでしか使えない機能もあるので、この機会にzshに乗り換えてみるのもいいかもしれません。
Ctrl+r
インクリメンタルなキーワード検索です。
Ctrl+p, Ctrl+n
Ctrl+p でヒストリの一つ前に戻ります。
Ctrl+n でヒストリの一つ次に進みます。
前後に目的のコマンドがあることがわかっている場合に有効です。
Meta+p, Meta+n
zshでしか使えません(たぶん)。
cshでも使えるようです。
入力したコマンドで始まるヒストリの履歴のみ、Ctrl+p, Ctrl+nと同じようにたどります。
例えば、"mysql" と入力してMeta+p, Meta+nを押すとmysqlで始まるヒストリだけたどれます。
Ctrl+o
zshでしか使えません(たぶん)。
Enter(Ctrl+m)の代わりにCtrl+oで実行すると、実行後のプロンプトにヒストリ内の次のコマンドが自動で入力されます。
ヒストリ内の一連のコマンドを実行するときに便利です。
言葉で説明するのが難しいので、実際に使ってみるとわかると思います。
grep $HOME/.historyhistory|grep foo
ヒストリを直接grepします。
乱暴な方法ですが、非常に便利です。
まとめ
コマンドラインの便利さが伝わったでしょか(伝わってないかな)。
プログラミングしてない人にプログラムの便利さを伝えるのが難しいように、コマンドラインを使ってない人にコマンドラインの便利さを伝えるのはなかなか難しいのかもしれません。
プログラミングは最初は慣れるまで時間がかかりますが、慣れたら非常に便利です。
コマンドラインもプログラミングと同じで、慣れるまで時間がかかりますが、慣れたら非常に便利です。
コマンドラインもプログラミングと似たようなエッセンスがありますので、ぜひともチャレンジしてみてはいかがでしょうか。

コメント
grep $HOME/.history ですが ~/.history の方が短く良くありません?
こっちだと何か副作用などがあるのでしょうか。
投稿者: pollux | 2008年5月21日 12:32
> pollux
おっしゃる通り
僕も基本的には "~" を使うんですが、$HOMEの方が分かりやすいかなと思って
あえて副作用をあげるなら "~" は "" の中で展開されないぐらいでしょうか
投稿者: masato | 2008年5月21日 13:12
zshは使ってませんが
> grep $HOME/.history
は個人的には
history | grep hoge
かなぁ
投稿者: kousuke | 2008年5月21日 14:14
単純に history | grep aaa では×ですか?
投稿者: tourisugari | 2008年5月21日 15:30
> $HOMEの方が分かりやすいかなと思って
そういうことだったのですね。すみませんちょっと気になったもので。
ありがとうございました。
投稿者: pollux | 2008年5月21日 19:18
自分は新規ファイルの追加は
svn add * --force
としています。
投稿者: shmz | 2008年5月21日 23:45
> kousuke, tourisugari
確かにおっしゃる通りですね
変更しました
投稿者: masato | 2008年5月22日 00:20
> shmz
そのやり方で再帰的に処理できるのでしょうか
投稿者: masato | 2008年5月22日 00:32
--forceをつけることで再帰的に処理してくれます。
投稿者: shmz | 2008年5月22日 07:28
> shmz
なるほど。--forceは知りませんでした。
あざっす!!
投稿者: masato | 2008年5月22日 08:13
説明間違えてました。
svn add
svn up
svn st
などは再帰的に処理するのがデフォルトで
svn add * -N
とするとカレントディレクトリのみ処理します。
svn add *
とするとすべてのファイルをaddしようとします。
すでにsvnで管理されているファイルだとwarningで表示されるので
--forceオプションをつけることで
強制的に実行することができます
(このときwarningは表示されません)
投稿者: shmz | 2008年5月22日 23:17