今回はLinuxコマンドであるfindコマンドについて解説します
ファイル名・更新日時・サイズなど、さまざまな条件でファイルを探せるコマンドです
古いログの削除やディスク容量の調査など、インフラの現場で毎日のように使うのでぜひ覚えて帰ってくださいね!
※注 本文の△は半角スペースに置き換えてください。わかりやすくするために△で記述してます
findコマンドとは??
findコマンドは、指定したディレクトリの下を再帰的にたどって、条件に合うファイルやディレクトリを探すコマンドです
名前・種類・更新日時・サイズ・権限などで絞り込めるうえ、見つけたファイルに対してそのままコマンドを実行することもできます
よく比較されるgrepは「ファイルの中身」から文字列を探すコマンドで、findは「ファイルそのもの」を探すコマンドです
役割が違うので、組み合わせて使うととても強力です
この記事の実行結果は、GNU findutils 4.9.0(Ubuntu 24.04)のfindで確認しています
findコマンドの主なオプション
findコマンドには、検索条件を指定するオプションがたくさんあります
| オプション | 意味 |
|---|---|
| -name | ファイル名で検索するオプション |
| -iname | 大文字・小文字を区別せずにファイル名で検索するオプション |
| -type | 種類で絞り込むオプション |
| -mtime / -mmin | 更新日時で検索するオプション |
| -size | ファイルサイズで検索するオプション |
| -empty | 空のファイル・ディレクトリを検索するオプション |
| -maxdepth | 探す深さを制限するオプション |
| -perm | パーミッションで検索するオプション |
| -exec | 見つけたファイルに対してコマンドを実行するオプション |
| -delete | 見つけたファイルを削除するオプション |
ここからは、次のコマンドで作ったテスト用ディレクトリを使って動きを確認していきます
コマンドはすべて、testディレクトリを作った場所(カレントディレクトリ)で実行します
mkdir△-p△test/docs△test/empty_dir△test/logs△test/scripts
echo△”Please△read△me△first.”△>△test/docs/README.TXT
touch△test/docs/empty.txt
printf△’memo:△buy△milk\nmemo:△call△Tanaka-san\n’△>△test/docs/memo.txt
touch△-d△”40△days△ago”△test/docs/memo.txt
echo△”2026-11-01△09:00:00△INFO△app△started”△>△test/logs/app.log
echo△”2026-10-22△09:00:00△INFO△app△started”△>△test/logs/app.log.1
touch△-d△”10△days△ago”△test/logs/app.log.1
seq△-f△”2026-10-31△12:00:00△INFO△request△id=%05g△done”△1△43000△>△test/logs/big.log
printf△’#!/bin/bash\ntar△czf△/tmp/backup.tar.gz△test/docs\n’△>△test/scripts/backup.sh
chmod△u+x△test/scripts/backup.sh
# memo.txtは40日前、app.log.1は10日前に更新したことにしています
# big.logは43000行(約2MB)のログ、empty.txtは中身が空、empty_dirは空のディレクトリです
ls△-lR△test
実行結果:
test:
total 16
drwxrwxr-x 2 user user 4096 Nov 1 12:04 docs
drwxrwxr-x 2 user user 4096 Nov 1 12:04 empty_dir
drwxrwxr-x 2 user user 4096 Nov 1 12:04 logs
drwxrwxr-x 2 user user 4096 Nov 1 12:04 scripts
test/docs:
total 8
-rw-rw-r– 1 user user 22 Nov 1 12:04 README.TXT
-rw-rw-r– 1 user user 0 Nov 1 12:04 empty.txt
-rw-rw-r– 1 user user 37 Sep 22 12:04 memo.txt
test/empty_dir:
total 0
test/logs:
total 1984
-rw-rw-r– 1 user user 37 Nov 1 12:04 app.log
-rw-rw-r– 1 user user 37 Oct 22 12:04 app.log.1
-rw-rw-r– 1 user user 2021000 Nov 1 12:04 big.log
test/scripts:
total 4
-rwxrw-r– 1 user user 49 Nov 1 12:04 backup.sh
cat△test/docs/README.TXT
実行結果:
Please read me first.
cat△test/docs/memo.txt
実行結果:
memo: buy milk
memo: call Tanaka-san
cat△test/logs/app.log
実行結果:
2026-11-01 09:00:00 INFO app started
cat△test/logs/app.log.1
実行結果:
2026-10-22 09:00:00 INFO app started
head△-n△3△test/logs/big.log
実行結果:
2026-10-31 12:00:00 INFO request id=00001 done
2026-10-31 12:00:00 INFO request id=00002 done
2026-10-31 12:00:00 INFO request id=00003 done
cat△test/scripts/backup.sh
実行結果:
#!/bin/bash
tar czf /tmp/backup.tar.gz test/docs
-name
ファイル名で検索するオプション
*(任意の文字列)や?(任意の1文字)といったワイルドカードが使えます
find△test△-name△”*.log”
実行結果:
test/logs/big.log
test/logs/app.log
パターンは必ずダブルクォートで囲みましょう
囲まないと、findに渡る前にシェルが*.logを展開してしまい、意図しない結果やエラーになることがあります
また、-nameはファイル名全体とマッチするかで判定するので、app.log.1は「.log」で終わっていないため表示されません
-iname
大文字・小文字を区別せずにファイル名で検索するオプション
README.TXTのように大文字・小文字が混在していそうなときに便利です
find△test△-iname△”readme.txt”
実行結果:
test/docs/README.TXT
-type
種類で絞り込むオプション
よく使うのはf(通常ファイル)、d(ディレクトリ)、l(シンボリックリンク)の3つです
find△test△-type△d
実行結果:
test
test/scripts
test/logs
test/empty_dir
test/docs
-mtime / -mmin
更新日時で検索するオプション
-mtimeは「最終更新から何日経ったか」、-mminは「何分経ったか」で絞り込みます
+7は「7日を超えて経過(実質8日以上前)」、-1は「1日(24時間)未満」という意味です
find△test△-type△f△-mtime△+7
実行結果:
test/logs/app.log.1
test/docs/memo.txt
# 更新から7日を超えたファイルを表示
findは経過時間を「24時間単位で切り捨てた日数」で比べるので、+7は7日と23時間経っただけでは当たりません
ログ削除などで日数を決めるときは、1日ずれることを意識しておきましょう
-size
ファイルサイズで検索するオプション
単位はk(KiB)、M(MiB)、G(GiB)などが使えて、+で「より大きい」、-で「より小さい」です
find△test△-type△f△-size△+1M
実行結果:
test/logs/big.log
-empty
空のファイル・ディレクトリを検索するオプション
find△test△-empty
実行結果:
test/empty_dir
test/docs/empty.txt
-maxdepth
探す深さを制限するオプション
-maxdepth 1にすると、指定したディレクトリの直下だけが対象になります
find△test△-maxdepth△1
実行結果:
test
test/scripts
test/logs
test/empty_dir
test/docs
# -maxdepthを-typeの後ろに書いた場合
find△test△-type△d△-maxdepth△1
実行結果:
find: warning: you have specified the global option -maxdepth after the argument -type, but global options are not positional, i.e., -maxdepth affects tests specified before it as well as those specified after it. Please specify global options before other arguments.
test
test/scripts
test/logs
test/empty_dir
test/docs
-maxdepthは他の条件より前(ディレクトリ指定の直後)に書くのがおすすめです
後ろに書いても結果は同じですが、端末から実行すると上のような警告メッセージが出ます
-perm
パーミッションで検索するオプション
-perm -u+xは「所有者の実行権限が付いているもの」という意味です
find△test△-type△f△-perm△-u+x
実行結果:
test/scripts/backup.sh
-exec
見つけたファイルに対してコマンドを実行するオプション
{}の部分が見つかったファイルのパスに置き換わり、最後の\;がコマンドの終わりの印です
find△test△-name△”*.log”△-exec△ls△-lh△{}△\;
実行結果:
-rw-rw-r– 1 user user 2.0M Nov 1 12:04 test/logs/big.log
-rw-rw-r– 1 user user 37 Nov 1 12:04 test/logs/app.log
# 日時やユーザー名は環境によって異なります
-delete
見つけたファイルを削除するオプション
削除は元に戻せないので、使い方は後ほど「古いログファイルを削除する」で詳しく解説します
基本的な使い方
findコマンドの基本的な構文は「find△検索を始めるディレクトリ△条件△アクション」となります
ディレクトリを省略するとカレントディレクトリ(.)、アクションを省略すると-print(パスを表示)になります
条件を複数並べると「かつ(AND)」として扱われます
find△test
実行結果:
test
test/scripts
test/scripts/backup.sh
test/logs
test/logs/big.log
test/logs/app.log.1
test/logs/app.log
test/empty_dir
test/docs
test/docs/README.TXT
test/docs/empty.txt
test/docs/memo.txt
# test配下をすべて表示
find△test△-name△”*.txt”
実行結果:
test/docs/empty.txt
test/docs/memo.txt
# 名前が.txtで終わるものを表示(大文字のREADME.TXTは対象外)
find△test△-type△f△-name△”*.log”
実行結果:
test/logs/big.log
test/logs/app.log
# ファイルだけに絞って、名前が.logで終わるものを表示
find△.△-name△”memo.txt”
実行結果:
./test/docs/memo.txt
# カレントディレクトリ以下からmemo.txtを探す
表示される順番はファイルシステム上の並び順なので、lsのように名前順にはなりません
条件を組み合わせる(AND・OR・NOT)
条件を並べるとANDになりますが、ORやNOTも使えます
# NOT(!):.logで終わらないファイル
find△test△-type△f△!△-name△”*.log”
実行結果:
test/scripts/backup.sh
test/logs/app.log.1
test/docs/README.TXT
test/docs/empty.txt
test/docs/memo.txt
# OR(-o):.shまたは.txtのファイル
find△test△-type△f△\(△-name△”*.sh”△-o△-name△”*.txt”△\)
実行結果:
test/scripts/backup.sh
test/docs/empty.txt
test/docs/memo.txt
-oを使うときは、ORでまとめたい部分をカッコで囲むのがポイントです
カッコはシェルにとって特別な記号なので、\( \)のようにバックスラッシュでエスケープし、前後にスペースを入れてください
カッコを付けないと「-type fかつ*.sh」または「*.txt」と解釈され、ディレクトリまで拾ってしまうことがあります
見つけたファイルを一括処理する(-exec・xargs)
findの真価は「探したあと、そのまま処理できる」ところです
# -exec … {} + でまとめて1回実行する(grepと組み合わせ)
find△test△-name△”*.txt”△-exec△grep△-l△”memo”△{}△+
実行結果:
test/docs/memo.txt
# .txtファイルの中から「memo」を含むファイル名だけを表示
# xargsと組み合わせる
find△test△-name△”*.log”△-print0△|△xargs△-0△wc△-l
実行結果:
43000 test/logs/big.log
1 test/logs/app.log
43001 total
最後を\;ではなく+にすると、見つかったファイルをまとめて1回のコマンドに渡すので、ファイル数が多いときにずっと速くなります
xargsを使うときは、ファイル名にスペースが含まれていても安全なように、find側は-print0、xargs側は-0をセットで使いましょう
findコマンドの実用的な活用例
実際の現場でよく使われるfindコマンドの活用例をご紹介します
古いログファイルを削除する
ローテーションされた古いログのうち、7日を超えて経過したものを削除する例です
※削除は元に戻せません!必ず最初に-deleteを付けずに実行して、対象を確認してください
# 1. まずは対象の確認(何も消えません)
find△test/logs△-type△f△-name△”*.log.*”△-mtime△+7
実行結果:
test/logs/app.log.1
# 2. 対象が正しいことを確認してから削除
find△test/logs△-type△f△-name△”*.log.*”△-mtime△+7△-delete
ls△test/logs
実行結果:
app.log big.log
-deleteを使うときは、次の3点に注意してください
1つ目は、-deleteは必ず最後に書くことです
find . -delete -name “*.log”のように条件より前に書くと、絞り込む前にカレント配下がすべて削除されてしまいます
2つ目は、検索開始ディレクトリを絶対に間違えないことです
/やホームディレクトリを指定して実行すると、取り返しのつかない被害になります
3つ目は、root(sudo)での実行は特に慎重にすることです
-exec rm -rf {} \;のようにrm -rfと組み合わせる書き方も見かけますが、ディレクトリごと削除されるので非常に危険です
初心者のうちは使わないことをおすすめします
1ファイルずつ確認しながら処理する
-execの代わりに-okを使うと、実行前に1件ずつ確認してくれます
yを入力したものだけ実行されるので、削除のような操作も安心です
# 事前準備:前の節で削除したapp.log.1を作り直す
echo△”2026-10-22△09:00:00△INFO△app△started”△>△test/logs/app.log.1
ls△test/logs
実行結果:
app.log app.log.1 big.log
find△test/logs△-name△”app.log.1″△-ok△rm△{}△\;
実行結果:
< rm … test/logs/app.log.1 > ? n
# nを入力したので削除されません
ls△test/logs
実行結果:
app.log app.log.1 big.log
大きなファイルを探してディスクを空ける
「ディスク使用率が90%を超えた!」というアラート対応で、まず最初に打つことが多いコマンドです
# /var配下の100MBを超えるファイルを探す
sudo△find△/var△-type△f△-size△+100M△-exec△ls△-lh△{}△+
# 見つかったファイルを消すかどうかは、用途を確認してから判断しましょう
# 1時間以内に更新された設定ファイルを探す
sudo△find△/etc△-type△f△-mmin△-60
# 「誰かが設定を変えたかも?」という障害調査で役立ちます
トラブルシューティング
findコマンド使用時によくある問題と解決法です
Permission deniedが大量に出る
一般ユーザーで/などを検索すると、読めないディレクトリについてエラーが大量に出ます
find△/△-name△”nginx.conf”
実行結果:
find: ‘/etc/redis’: Permission denied
find: ‘/etc/credstore.encrypted’: Permission denied
find: ‘/etc/polkit-1/rules.d’: Permission denied
…
# 読めないディレクトリの数だけエラーが続きます
# エラーを非表示にする
find△/△-name△”nginx.conf”△2>/dev/null
# この環境にはnginxを入れていないので、エラーが消えて何も表示されません
ただし、読めないディレクトリの中は検索されていないので「見つからない=存在しない」とは限りません
確実に探したいときはsudoを付けて実行しましょう
-size -1Mで探すと空ファイルしか出ない
-sizeは、ファイルサイズを指定した単位で切り上げてから比較します
そのため-size -1Mは「1MiB未満」ではなく「切り上げて0MiB」、つまり空のファイルだけにマッチします
find△test△-type△f△-size△-1M
実行結果:
test/docs/empty.txt
# 1MiB未満を探したいときは小さい単位で指定する
find△test△-type△f△-size△-1024k
実行結果:
test/scripts/backup.sh
test/logs/app.log.1
test/logs/app.log
test/docs/README.TXT
test/docs/empty.txt
test/docs/memo.txt
# バイト単位で厳密に指定する(cはバイト)
find△test△-type△f△-size△-1048576c
実行結果:
test/scripts/backup.sh
test/logs/app.log.1
test/logs/app.log
test/docs/README.TXT
test/docs/empty.txt
test/docs/memo.txt
# 約2MBのbig.log以外がすべて表示されます
ワイルドカードをクォートし忘れる
find . -name *.logのようにクォートを忘れると、カレントディレクトリに.logファイルがあった場合にシェルが先に展開してしまいます
-nameのパターンは常にクォートすると覚えておきましょう
まとめ
いかがでしたでしょうか
今回はfindコマンドについてまとめてみました
findコマンドは「ファイルそのもの」を条件で探すコマンドで、-name・-type・-mtime・-sizeの4つを覚えればほとんどの場面に対応できます
-execやxargsと組み合わせると見つけたファイルを一括処理できますが、-deleteやrmとの組み合わせは必ず事前に対象を確認してから実行しましょう
インフラエンジニアなら毎日のように使うコマンドなので、ぜひマスターしてください!
