findの便利な近い方

先日の「UNIXコマンド これだけは覚えておけ!」に続いて、同じサイトから今回は、findコマンドについての記事の抜粋&意訳&補足です。

 

findコマンドはUNIXの中でも最も便利なコマンドの1つです。もしあなたがJavaやC++のプログラマで、UNIX環境で作業してるなら、IDEが無くても、ソースファイル中の任意のワードを探すのにfindコマンドが役に立ちます。

 

  • !find で、最後に実行したfindコマンドを再実行

    findコマンドは引数も含めて長くなりがちです。コマンドの前に!をつけると最後に実行した形式で同じをコマンドを実行することができます。

    
    !find 
    

    と入力して、再実行しましょう。

     

  • 1日以内、1時間以内、1分以内に変更したファイルを探す。

    -mtime オプションを使うと、ファイルの変更日時を指定して探すことができます。問題が起きたときに、最近どのファイルが変更されたのかを探す時などに便利です。

    他にもタイムスタンプに関連したオプションが2つあります。

    -atime は最後にアクセスされた日時で探すことができるオプションです。また、-ctimeは、ファイルステータスが変更された日時で探すためのオプションです。

    
    # 1日前(24時間以上48時間以内)に変更されたファイルを探す
    find . -mtime 1 
    
    
    # 変更されて1日(24時間)たっていないファイルを探す
    find . -mtime -1 
    
    
    # 変更されて2日(48時間)以上たったファイルを探す
    find . -mtime +1
    

    日じゃなくて、時間や分で指定する場合は、hやmをつけて実行します。

    
    find . -mtime -10h
    

     

  • パーミッションが777のファイルやディレクトリを探す

    -permオプションで、パーミッションを指定して探すことができます。

    
    find . -perm 644
    

    全ての権限が許可されたファイル/ディレクトリを探すには、

    
    find . -perm 777
    

    と指定します。

    ここまでの例で、findの直後につけている「 .」 はカレントディレクトリを指しています。find は指定したディレクトリ内をサブディレクトリも含めて横断的に探してくれます。他のディレクトリの中を探す場合は、

    
    find /some/path/to/find -perm 644
    

    のように、パスを指定して実行します。

     

  • 大文字/小文字を区別せずに探す

    -name をオプションを使うと名前を指定して探すことができますが、デフォルトでは大文字と小文字が区別されます。-iname オプションを使うと、大文字と小文字を区別せずに探すことができます。

    
    find . -iname "error" -print
    

     

    xargsコマンドをfindと組み合わせて使うと便利です。xargsコマンドを使うと、findで見つかったファイルを削除したり、中身を表示したりすることができます。

     

  • findを使って、一時ファイルを削除する

    
    find . -name "*.tmp" -print | xargs rm -f
    

    ファイルを削除するには、xargsとの組み合わせを使う以外に、find自体の-deleteオプションを使う方法もあります。 検索結果にホワイトスペースを含むようなパスがある場合は、findの-print0と、xargsの-0オプションを使えば問題を回避できます。(この記事の下の方にも説明があります)

     

  • Exceptionの文字を含む全てのテキストファイルを探す

    findの結果にgrepを使えば、特定の文字が含まれているものだけを見つけることができます。

    
    find . -name "*.txt" -print | xargs grep "Exception"
    

    -printオプションはデフォルトなので指定しなくても構いません。

     

  • サブディレクトリは探さないようにする

    指定したディレクトリ内のみを探し、その下のサブディレクトリまでは探さないでよい場合は、-maxdepthオプションでディレクトリの深さを指定します。

    
    find . -maxdepth 0 -type f -newer first_file
    

    -maxdepthに0を指定すると、そのディレクトリ内のみ探します。1を指定すると、1つ下のレベルのサブディレクトリまで探します。

    -type は探す対象のタイプを指示します。fはファイルを探すことを指示しています。dを指定するとディレクトリを探します。

    -newer は指定したファイルよりタイムスタンプが新しいファイルを探すことを指示します。

    他のやり方として、

    
    find . -type f -cmin 15 -prune
    

    といった指定の仕方もあります。

    -cminで15分前に変更されたファイルを指定し、-pruneで、サブディレクトリを探さないことを指定しています。

    ※-pruneは、引数の指定により意味が変わってきます。

     

  • ファイルサイズを指定して探す

    
    find . -size +1000c -exec ls -l {} \;
    

    -size オプションを使うと、指定したファイルサイズのファイルを探すことができます。Byteで指定する場合は数値の後にcをつけます。KByteの場合は、kです。cやkをつけないと、ブロックサイズを意味することになるので分り難くなります。

    数値の前に-(マイナス)をつけると、指定したサイズより小さいファイルを探します。+(プラス)をつけると、指定したサイズより大きいファイルを探します。

    サイズの範囲を指定したい場合は、

    
    find . -size +100k -size -500k -print 
    

    のように指定します。この場合、ファイルサイズが100kbより大きく、500kbより小さいファイルを探します。

     

  • 古い大きなファイルを探す

    -mtimeオプションと-sizeオプションを組み合わせて使うと、指定日以上触られていないサイズの大きなファイルを探すことができます。例えば空き容量を増やすために、古い大きなファイルを削除したい時などに使えます。

    
    find . -mtime +10 -size +500k -exec ls -l {} \;
    

    この例では、11日以上変更されていない、500Kbを超えるサイズのファイルを探しています。

     

  • awkコマンドと組み合わせて使う

    findの結果をawkに渡して、例えば出力結果の特定の列のみ表示させることができます。

    
    find . -type l -print | xargs ls -ld | awk '{print $11}'
    

    上の例では、シンボリックリンクを探して、リンク元を出力しています。「-type l」でシンボリックリンクを指定しています。

    ※$11はshellから渡されるパラメータで、この場合、lsの出力結果のスペースで区切られた中での11番目のフィールドを意味しています。

     

  • スペースを含むファイルがある場合

    xargsは、スペースで区切られた値を個別の引数とみなすので、ファイル名にスペースが含まれていると、正しく処理できなくなります。 findのオプショに「-print」(デフォルト)の代わりに、「-print0」を、xargsのオプションに「-0」をつけることで、この問題を解決できます。これらは、文字列をスペース区切りではなくNULL終端文字列(文字列をNULL(0)で区切る)として扱うためのオプションです。(常にこのオプションを使うようにした方がいいかもしれません)

    
    find .
    .
    ./Documents and Settings
    ./tmp
    ./work
    

    ここでは、3つのディレクトリがありますが、1つはスペースを含んだディレクトリです。これをそのまま、xargsに渡すとエラーメッセージが表示されます。

    
    find . | xargs ls
    ls: ./Documents: No such file or directory
    ls: Settings: No such file or directory
    ls: and: No such file or directory
      :
    

    find に「-print0」をつけて、xargsのオプションに「-0」をつけると上手く処理できます。

    
    find . -print0 | xargs -0 ls -l
    

     

Macには、Spotliteという超便利な機能があるので出番は少ないかも知れませんが、ターミナルで作業している時や、条件をつけてファイルやディレクトリを探したい時にはfindコマンドは便利です。findコマンドの使い方を覚えれば作業効率もいっそう上がると思います。