findコマンドとxargsの組み合わせ術:ファイル検索から一括処理(exec)までの実務レシピ

ファイル操作/圧縮

サーバー運用やログ解析において、「特定の条件に合致するファイルを探し出し、それらに対して一括で処理を行う」という作業は日常茶飯事です。この用途で最強の組み合わせとなるのが、find コマンドと -exec オプション、そして xargs コマンドです。

本記事では、単なる検索オプションの解説にとどまらず、実務でそのまま使える「検索して一括処理する」ためのレシピを厳選して紹介します。

1. find コマンドの基本と実務で使うオプション

find コマンドの基本的な構文は以下の通りです。

find [検索パス] [検索条件] [アクション]

実務で頻繁に使用する検索条件(オプション)は限られています。以下の表にまとめました。

オプション意味実務での使用例
-nameファイル名で検索(ワイルドカード可)-name "*.log"
-typeファイルタイプで検索(f:ファイル, d:ディレクトリ)-type f
-mtime更新日時で検索(+N:N日より前, -N:N日以内)-mtime +30(30日以上前のファイル)
-sizeファイルサイズで検索(+N:Nより大きい)-size +100M(100MB以上のファイル)

注意点: -name でワイルドカード(*)を使用する場合は、必ずクォーテーション(" " または ' ')で囲んでください。囲まないと、シェルによってカレントディレクトリのファイル名に展開されてしまい、意図しない動作を引き起こします。

2. 検索結果に対してコマンドを実行する(-exec)

見つけたファイルに対して、直接コマンドを実行できるのが -exec アクションです。

find /var/log/app -name "*.log" -mtime +30 -exec rm {} \;

このコマンドは、「/var/log/app 配下の .log ファイルのうち、更新日時が30日より前のものを削除(rm)する」という処理を行います。

-exec の構文ルール

  • {} : find で見つかったファイルパスに置き換わります。
  • \; : -exec で実行するコマンドの終わりを示します(セミコロンをシェルからエスケープするためにバックスラッシュが必要です)。

+ を使った効率的な実行

\; の代わりに + を使用すると、見つかった複数のファイルをまとめて1つのコマンドの引数として渡すことができます。

# 1ファイルずつ rm を実行(ファイル数だけプロセスが起動する)
find . -name "*.tmp" -exec rm {} \;

# まとめて rm を実行(効率的)
find . -name "*.tmp" -exec rm {} +

3. xargs を使ったより高度な一括処理

-exec よりも柔軟で、パイプ(|)と組み合わせて強力な処理を実現できるのが xargs コマンドです。xargs は標準入力から受け取ったリストを、指定したコマンドの引数として渡します。

find と xargs を組み合わせる際の鉄則(-print0 と -0)

ファイル名にスペースが含まれている場合、通常の xargs ではスペースで区切られた別々のファイルとして認識されてしまい、エラーになります。これを防ぐために、find 側で -print0(ヌル文字区切りで出力)、xargs 側で -0(ヌル文字区切りで受け取る)を使用するのが鉄則です。

find /path/to/search -type f -name "*.txt" -print0 | xargs -0 grep "ERROR"

4. 実務でそのまま使えるレシピ集

レシピ1:古いログファイルを一括で圧縮(gzip)する

ログローテーションが設定されていない環境などで、手動で古いログを圧縮したい場合に使用します。

# 7日以上前の .log ファイルを gzip で圧縮
find /var/log/myapp -type f -name "*.log" -mtime +7 -print0 | xargs -0 gzip

レシピ2:特定の文字列を含むファイルを検索し、該当箇所を表示する

プロジェクト内の全ソースコードから、特定の関数名やエラーメッセージを探し出す際によく使います。

# .php ファイルの中から "TODO" という文字列を探す
find /var/www/html -type f -name "*.php" -print0 | xargs -0 grep -n "TODO"

レシピ3:空のディレクトリを一括で削除する

不要になった一時ディレクトリなどを整理する際に便利です。

# 空のディレクトリ(-empty)を検索して削除
find /tmp/cache -type d -empty -exec rmdir {} +

レシピ4:パーミッションが不適切なファイルを一括修正する

Webサーバーの公開ディレクトリなどで、ファイルやディレクトリの権限を正しく設定し直すための定番コマンドです。

# ディレクトリの権限を 755 に設定
find /var/www/html -type d -exec chmod 755 {} +

# ファイルの権限を 644 に設定
find /var/www/html -type f -exec chmod 644 {} +

5. 破壊的操作を行う前の安全確認

rmchmod などの破壊的操作を伴うコマンドを実行する際は、必ず事前にアクション(-exec や xargs)を外した状態で実行し、対象となるファイルのリストを目視確認してください。

# 1. まずはリストだけを出力して確認
find /var/log -name "*.log" -mtime +30

# 2. 問題なければ -exec や xargs を付与して実行
find /var/log -name "*.log" -mtime +30 -exec rm {} +

まとめ

find コマンドは単なる「検索ツール」ではなく、-execxargs と組み合わせることで、強力な「一括処理ツール」へと進化します。特に -print0xargs -0 の組み合わせは、スペースを含むファイル名による事故を防ぐためのベストプラクティスですので、ぜひ手に覚えさせてください。

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする