2012年9月30日日曜日

ファイルを探すコマンド

Finderの「このアプリケーションで開く」その2や、locateデータベースを作る方法の中でlocateコマンドでファイルを探す記事を書きました。自分の場合、どのようにファイルを探したり思い出したりするのにどんな方法を使っているか主なところを書いてみます。この記事ではターミナルというかシェル(bash)を使う場合について書いています。

次の3つの使用場面で分けてみました。(1) 現在のディレクトリ内を探したい場合、(2) 現在または特定のディレクトリとそのサブディレクトリ含めて探したい場合、(3) コマンド名を探したい場合の3つです。

(1) まず、はじめは、現在のディレクトリ内ですね。
lsコマンドを使う場合が多いです。普通すぎますね。lsコマンドは、現在自分のいるディレクトリや、指定したディレクトリのファイル名を表示します。よく使うのは、単純な
$ ls
と、作成時間の順に表示する
$ ls -lt (または $ ls -ltr )
です。
-ltオプションは、ファイルの変更時間が新しい順に表示します。-ltrオプションのように-rを追加すると古い順に表示します。最近使ったファイル名をしりたい場合が多いので、-rを指定すると次のコマンドプロンプトの近くにファイル名が表示されて便利です。-rを使わないと、最近のファイルが画面からスクロールアウトしてしまう場合も多いですしね。
ファイルが多い場合は、lessやhead, tailで画面外に出ないようにすることもあります。
また、多少ファイルが多い場合は、ls a*.html のようにワイルドカードで一部を指定したりすることもあります。
同じディレクトリ内ですと、ほとんどlsで用が足りますね。

(2) 次は、現在ディレクトリとそのサブディレクトリすべて、またはあるディレクトリとそのサブディレクトリ以下をすべて探す場合です。現在いるディレクトリや特定のディレクトリの場合は、findコマンドを使う場合が多いですがlocateコマンドも使います。
$ find . -name "*foobar*"
上のfindコマンドの場合は、"."は、カレントディレクトリを示すので、現在のディレクトリ以下から探すことを意味し、-nameコマンドでファイル名の一致条件を指定します。この場合は、ファイル名の一部に"foobar"を含むファイルを探して表示します。ファイル名の大文字、小文字の区別をしない場合は、-inameオプションが使えます。
また、ファイル名の代わりにディレクトリ名を探す場合は、次のように-type dを追加します。
$ find . -type d -iname "application*"
探したいファイルが、特定のディレクトリの下にあるとわかっている場合は、例えば
$ find /opt/local -name "a*.conf"
のようにするか、そのディレクトリに移動後(cd /opt/local)、探したいパス名の部分に"."を指定しています。後でフルパス名を使いたい場合が多いので、初めの方法をよく使います。
findコマンドは他にも時間指定したり、見つかったファイルに対して処理を行うオプションなどがあるので調べると面白い使い方が出来ると思います。

locateコマンドは、ファイルがどこにあるかわからない場合や、findコマンドで探すとディレクトリ階層の上位(/に近い場合)で、その下にファイルが大量にある場合、まず、locateコマンドを使ってみるという使い方が多いです。使い方は、単純に
$ locate "ファイル名の一部"
とすることが多いです。
locateコマンドはfindコマンドに比べスピードが速いのですが、

  • データベースを作っておく必要があります。
  • データベースは、設定にもよりますが一週間に一回しか更新されないので最近作成したファイルは見つけられません。
  • 検索する単語が短かかったり、パス名の上の階層に一致する場合は出力が多すぎて、そこからさらに絞り込まないといけない場合が結構あります。
  • Macを個人で使っている場合はあまり関係ないかもしれませんが、サーバーのように他の人も使う場合、他のユーザからファイル名が見られてしまうというセキュリティ上の問題があります。

といったことを注意しておく必要があります。
実行ファイルのコマンド名を忘れた場合に限られますが、which、

(3) 最後の場合として、コマンド名を探す場合です。
よく使うのは、whichコマンドです。
$ which curl
などのように、コマンド名を指定します。シェルがbashの場合、whichコマンドは、現在指定しているPATHに従って有効なコマンドのパス名を表示します。例えば、/usr/localの下やMacPortsを使って標準以外の場所にも、標準と同名のコマンドをインストールしている場合、どれが使われているかを確認できます。
気をつけないといけないのは、実際はbashのビルトインコマンドを使っている場合やaliasで既存のコマンドと同じ名前でコマンド名を置き換えていても、ファイルシステム上に見つかったコマンドしか表示されない点です。私の環境で、cdとh、aaaを指定した場合ですが、以下のようになります。
$ which cd
/usr/bin/cd # whichの出力です
$ which h
$ # 何も表示されません。
$ which aaa
$ # 何も表示されません。
でも、実際は、cdは、bashの内部に組み込まれているcdコマンドが使われています。また、lsもalliasコマンドで、h='history | tail -40 | more'と設定しています。
最近はbashを使っているのですが、以前使っていたtcshでは、
% which cd
cd: shell built-in command.
% which h
h: aliased to history 25
% which aaa
aaa: Command not found.
のように、実際に使っているコマンド(historyもシェル組み込みコマンドです)が表示されます。見つからない場合も見つからないと表示されます。

また、which コマンドの引数には探したいコマンド名をフルネームで指定しないと結果が表示されないので、コマンド名を忘れていると使えないですね。
コマンド名を覚えておかないといけない欠点をカバーする方法として、bashの組み込みコマンドcompleteがありますね。コマンド名やファイル名の先頭部分を入力して、覚えている場合に、lsで始まるファイル名の候補を示してくれます。以下は、コマンドプロンプトに、which lsと入力し、tabキーを押した場合の表示です。
$ which ls[tab]

ls        lsdistcc  lsm       lsof      
lsbom     lslen.sh  lsmac     lsvfs
$ which ls
ここで、表示を見ながら入力を継続したり、例えば"v[tab]"と入力すると、lsvfsまで補完
してくれます。
$ which lsv[tab] # tabキーを押した瞬間、次の行のように表示されます。
$ which lsvfs
ファイル名を探す場合より、入力を結構便利です。
長くなったのでこのあたりで終わります。また、関連した話題を書きたいとおもいます。

0 件のコメント:

コメントを投稿