findコマンドを利用した便利なUNIXテクニック例
最後に、find
コマンドを利用したいくつかの例を紹介しておきます。なお、ここに紹介した書き方以外にも、様々な書き方があります。業務に合わせて応用しながら利用してください。
core、#*、*~を一括削除する
Emacsを利用していると、テキストを保存する際に「ファイル名~」、ファイルを編集する際に「#ファイル名#」というバックアップファイルが作成されます。また、Unix・Linuxプロセスが異常終了すると「core」ファイルが生成されます。これらのファイルを一度に削除したい場合には、次のように指定できます。
$ find . \( -name core -o -name '#*' -o -name '*~' \) -exec rm '{}' +
「\(
」と「コマンド」、「コマンド」と「\)
」の間にはスペースを空ける必要があります。
xargs
コマンドを利用する場合は、次のように指定できます。
$ find . \( -name core -o -name '#*' -o -name '*~' \) -print0 | xargs -0 rm
find
コマンドの判別式「-o
」は、「-or
」でも構いません。
なお、find
コマンドの「-delete
」アクションが利用できる場合は、次の方法が最も高速です。
$ find . \( -name core -o -name '#*' -o -name '*~' \) -delete
ユーザーが所有するファイルのみを検索して削除する
$ find . -type f -user $(whoami) -exec rm '{}' +
xargs
コマンドを利用する場合は、次のように指定できます。
$ find . -type f -user $(whoami) -print0 | xargs -0 rm
whoami
コマンドは、ユーザ名を表示します。
検索して見つかった全ファイルを移動する
検索して見つかった全ファイルを「/var/tmp/」以下に移動します。
$ find . -type f -print0 | xargs -0 mv -t /var/tmp/
mv
コマンドの「-t
」または「--target-directory
」オプションで、移動先ディレクトリを指定できます。なお、この例ではディレクトリ構造を維持せず、ファイルのみ移動します。同名のファイルが存在すると上書きされるなど期待通りに動かないため、注意が必要です。
xargs
コマンドに「-i
」(FreeBSDでは「-I
」)オプションをつけると、パイプで渡された結果を「{}
」で展開できます。このため、次の指定方法でも動作します。
$ find . -type f -print0 | xargs -0 -i mv '{}' /var/tmp/
FreeBSDの場合、デフォルトで「{}
」で展開できないため、次のように指定します。
$ find . -type f -print0 | xargs -0 -I % mv % /var/tmp/
「-I
」オプションの後の文字(例では「%
」)を、find
コマンドで見つかったファイル名に置換しています。
ただしこの方法は、1ファイルづつmv
コマンドを実行するため、処理が遅くなります。
FreeBSDでは、xargs
コマンドの「-J
」オプションを利用すると、「-I
」オプションより高速に処理できます。
$ find . -type f -print0 | xargs -0 -J % mv % /var/tmp/
この例では、検索して見つかったファイル名のグループを「%
」に置き換えてmv
コマンドを実行しています。
検索して見つかった全ファイルをディレクトリ構造ごとコピーする
検索して見つかった全ファイルを、ディレクトリ構造を保持したまま「/var/tmp/」以下にコピーします。これは、ファイル単位でバックアップを取る場合に、役に立ちます。ファイルのバックアップで利用するcpio
コマンドを利用すると次のように指定できます。
$ find . -type f -print0 | cpio -pd0 /var/tmp/
「-p
」オプションは、ファイルを別のディレクトリにコピーします。「-d
」オプションは、必要に応じてディレクトリを作成します。なお、cpio
コマンドの「-0
」オプションはGNUのcpio
コマンド以外では使えません。
サイズと拡張子を条件にファイルを検索し、結果を別のファイルに書き込む
「~/public_html」以下で、拡張子が「.gif」かつサイズが100Kバイト以上のファイルを探し、結果を「result.txt」ファイルに書き込みます。
$ find ~/public_html \( -name "*.gif" -a -size +100k \) -fprint result.txt
findコマンドの「許可がありません」を表示しない
一般ユーザーで、ルートディレクトリや「/etc」ディレクトリなどを対象に検索すると「Permission denied」という警告メッセージが大量に表示されます。検索結果の一覧が警告メッセージに埋まってしまい、検索結果の確認が大変な場合には、次の方法で表示されなくなります。
$ find / -name user → 「user」を検索 find: /usr/src: Permission denied → 警告メッセージ find: /usr/share/skel/MailBox: Permission denied → 警告メッセージ find: /usr/obj: Permission denied → 警告メッセージ (略) /home/user $ find / -name user 2>/dev/null /home/user
「2>/dev/null
」を指定して、警告メッセージをヌルデバイスへ出力しています。
まとめ
今回はfind
コマンドやgrep
コマンド、そしてxargs
コマンドを利用した「ファイル・ファイル内容の検索」に関するテクニックを紹介しました。今回紹介したほかにも、awkやperlを利用することで、簡潔な指定や高速な処理が可能な場合もあります。
次回以降も、テーマごとにUNIXテクニックを紹介していく予定です。