【Linux】find コマンドを使ってサーバ内のファイルを一括削除したい!
目次
はじめに
こんにちは。24 卒システムソリューション部のインフラエンジニア 1 年目 ぱる です。
気づけば年が明け、ビヨンドに入社してもうすぐ 1 年、時の流れの速さに怯えています⛄
今回は、実際の業務でお客様のサーバ内のファイル削除を頼まれたけど、量が多すぎて 1 つ 1 つ消すのは非効率すぎる!となったときに学んだ Linux コマンド「find」コマンドでのファイルの削除の方法についてご紹介します。
使いこなせれば便利ですが、1 つ間違えたら全く違うところがごっそり消えてしまう恐ろしいことも起こる可能性があるので、怖い思いをしないように使い方を練習していきたいと思います!
その他、初心者向けの Linux コマンド関連の記事もたくさんありますので気になったら見てみてください👀
【Linux】コマンドラインにある「~」「$」「#」ってどんな意味?【入門者向け】
find コマンドとは
基本書式
まず find コマンドとは、ファイルやディレクトリを検索したいときに利用される Linux コマンドです。
検索対象として、複数のファイルやディレクトリを指定することが可能です。
find コマンドの基本書式は下記の通りです。
find [検索対象のパス] [オプション] [アクション]
実際に当てはめてみるとこんな感じです。
find /var/log/test_log -name "file_1"-print
上記の内容としては、/var/log/test_log 配下にあるファイル名(-name "file_1")を指定して一覧表示(-print)させるというものです。
いくらでも加工して便利にできるので、複雑で難しそうなコマンドになっているものも見かけますが、基本の形はわりとシンプルです。この後の節で、オプションとアクションにももう少し触れていきます。
オプションの例
find コマンドで使用するオプションについてもご紹介します。
まだまだたくさんありますが、基本的なものと今回の記事で必要なコマンドを主に挙げておきます。
オプション | 説明 |
-name "[ファイル名]" |
ファイル名を指定して検索 |
-iname "[ファイル名]" |
ファイル名を指定して検索(文字の大小を区別しない) |
-path "[ファイル名]" |
パス名の部分文字列や特定のパターンを指定して一致するものを検索 |
-ipath "[ファイル名]" |
パス名の部分文字列や特定のパターンを指定して一致するものを検索(文字の大小を区別しない) |
-type [ファイルタイプ] |
ファイルのタイプを指定して検索 - type の後に f(通常のファイル)や d(ディレクトリ)を付けて指定できる |
-mtime "[日数]" |
指定した日数以前に更新されたファイルを検索 |
-atime "[日数]" |
指定した日数以前にアクセスされたファイルを検索する |
-newermt "[日時]" |
指定した日時以降に更新されたファイルを検索 |
アクションで削除を指定する方法
ここでいうアクションは、処理の方法を指します。
今回は、削除処理の方法にフォーカスしたいので、rm を用いた削除処理の方法について紹介したいと思います。
端的に削除をするといっても、削除の仕方は複数あります。
今回は、find コマンドで指定した複数のファイルを rm コマンドに渡して削除する際に使う「| xargs rm -p」「-exec rm {} +」「-exec rm {} \;」を例に挙げ、表にして比較してみました。
アクション | 処理の方法 | コマンドの説明 | 引数の扱い方 |
| xargs -p rm | 複数のファイルをまとめて rm へ渡すので、一度だけ rm が実行される → 大量のファイルを削除する際も処理が素早い |
「xargs」はオプションではなく 1 つのコマンド →「|」で繋げば様々なコマンドと併用可能 |
空白文字(スペースや改行など)を引数の区切りとして認識される →パス内にスペースが入っていると正しく認識されない可能性がある |
-exec rm {} + | 複数のファイルをまとめて rm へ渡すので、一度だけ rm が実行される → 大量のファイルを削除する際も処理が素早い |
「-exec」は find コマンドのオプションの 1 つ → 他のコマンドと併用できない |
引数が固定される → パス内にスペースがあっても引数を 1 つのかたまりとして認識してくれる |
-exec rm {} \; | 複数のファイルを 1 つ 1 つ rm に渡すので、ファイルの数だけ rm が実行される →大量のファイルを削除する際に処理が重く時間がかかる |
「-exec」は find コマンドのオプションの 1 つである → 他のコマンドと併用できない |
引数が固定される → パス内にスペースがあっても引数を 1 つのかたまりとして認識してくれる |
ざっくりとまとめましたが、この表を眺めていると「-exec rm -i {} \;」は「-exec rm {} +」より処理に時間がかかるし、良いところなくない…?と疑問に思いませんか?
確かに、膨大な量のファイルを削除するといった処理を実施したい場合に使うのには向いていませんが、あらかじめ引数の個数が固定であることを前提として作られたコマンドやプログラムには「-exec ~ {} \;」が活躍します。
例えば、「FileDeleter.exe」というプログラムを作成したとします。
このプログラムは、rm と同じように削除処理を実施できますが、受け取れる引数は 1 つだけです。
このプログラムと find コマンドを使って、file_1, file_2, file_3 というファイルを削除するとしましょう。
このとき、「-exec FileDeleter.exe {} +」を使うと file_1, file_2, file_3 をまとめて渡してしまうため、 1 つしか引数を受け取れない「FileDeleter.exe」は正しく実行できません。
逆に、「-exec FileDeleter.exe {} \;」を使えば、複数のファイルを 1 つ 1 つ「FileDeleter.exe」に渡すので、正しく実行できるのです。
今回用いる rm コマンドは、引数の個数が最大値を超えない限り受け取れる引数の個数は変動しますが、
中には例で挙げた「FileDeleter.exe」のように引数の個数が固定であることを前提に作成されているものがあります。
このような場合は、「-exec ~ {} +」では歯が立たないけど「-exec ~ {} \;」では確実に実行できる、みたいなことが起こる場合があります。
ですので、どのアクションを用いるかは対象となる引数に対してどんな処理を行いたいかで選択する必要があるのです!
長々と「-exec」の話をしましたが、
今回は複数のファイルを効率よく削除できて、他のコマンドにも併用可能な「xargs 」を用いてファイル削除を実施しようと思います。(使い勝手の良いコマンドを使いこなしたい✊)
find コマンドでファイルを削除してみよう!
削除する前に
今回、削除を実行するために下記のコマンドの書式を使います。
find [検索対象のパス] -type [タイプ] [オプション] '[日数 or 日時]' | xargs -p rm
「 xargs」は引数(ここでいう削除対象のファイルやディレクトリ)を受け取って、それを一度にコマンド(ここでいう rm)に渡しています。
「-p」は確認プロンプトを表示してくれるオプションです。削除しますか?の確認に対して「y」を答えないと消えないので、必ずつけておいた方がいいです。
補足ですが、指定パス配下にあるディレクトリもまるまる消したい場合は、「rm」にオプション「-r」 を付ける必要があります。
今回はファイルのみの削除で必要ないのでつけないでおきます。
最後に一番大事なことなのですが、保険の保険として、削除する前にいったん rm ではなく「ls」 を指定して実行してみてください。
正しくコマンドが入力できていれば、該当ファイルを探し出して表示してくれるだけなので、誤削除を防げます。
指定日時より前のファイルを削除
実際にやってみます。
1. ファイルを作成
以下のようなファイルを作成しました。
今回は 2024/12/5 より前に更新されたファイルをすべて消したいと思います。
[root@localhost test_log]# ll /var/log/test_log total 0 -rw-r--r--. 1 root root 0 Dec 1 2024 file_1 -rw-r--r--. 1 root root 0 Dec 2 2024 file_2 -rw-r--r--. 1 root root 0 Dec 3 2024 file_3 -rw-r--r--. 1 root root 0 Dec 4 2024 file_4 -rw-r--r--. 1 root root 0 Dec 5 2024 file_5 -rw-r--r--. 1 root root 0 Dec 6 2024 file_6 -rw-r--r--. 1 root root 0 Dec 7 2024 file_7 -rw-r--r--. 1 root root 0 Dec 8 2024 file_8 -rw-r--r--. 1 root root 0 Dec 9 2024 file_9
2. 削除対象ファイルの確認
オプション「! -newermt」を付けて、2024/12/5を指定します。
まずは、rm ではなく ls を指定し、2024/12/1 ~ 12/4 に更新されたファイル(file_1 ~ file_4)が検索出来ていることを確認をします。
ls しますか?と聞かれるので「y」を打ち込むと削除対象のファイルを表示してくれます。
[root@localhost ~]# find /var/log/test_log -type f ! -newermt 'Dec 5 2024' | xargs -p ls ls /var/log/test_log/file_2 /var/log/test_log/file_3 /var/log/test_log/file_4 /var/log/test_log/file_1?...y /var/log/test_log/file_1 /var/log/test_log/file_2 /var/log/test_log/file_3 /var/log/test_log/file_4
3. ファイルの削除
ちゃんと消したい対象のファイルが確認できればいよいよ削除です。
ls を rm に変えてコマンドを実行し、rm しますか?と聞かれるので、「y」を打ち込みます。
[root@localhost ~]# find /var/log/test_log -type f ! -newermt 'Dec 5 2024' | xargs -p rm rm /var/log/test_log/file_1 /var/log/test_log/file_2 /var/log/test_log/file_3 /var/log/test_log/file_4?...y
4. ファイルを確認
無事に消えました。
2024/12/5 より前に更新したファイルが消えていることが確認できます。
[root@localhost test_log]# ll /var/log/test_log total 0 -rw-r--r--. 1 root root 0 Dec 5 2024 file_5 -rw-r--r--. 1 root root 0 Dec 6 2024 file_6 -rw-r--r--. 1 root root 0 Dec 7 2024 file_7 -rw-r--r--. 1 root root 0 Dec 8 2024 file_8 -rw-r--r--. 1 root root 0 Dec 9 2024 file_9
指定日時より後のファイルを削除
続いて、 2024/12/5 より後に更新されたファイルをすべて消したいと思います。
1. ファイルを作成
先程と同様ファイルを作りました。
[root@localhost test_log]# ll /var/log/test_log total 0 -rw-r--r--. 1 root root 0 Dec 1 2024 file_1 -rw-r--r--. 1 root root 0 Dec 2 2024 file_2 -rw-r--r--. 1 root root 0 Dec 3 2024 file_3 -rw-r--r--. 1 root root 0 Dec 4 2024 file_4 -rw-r--r--. 1 root root 0 Dec 5 2024 file_5 -rw-r--r--. 1 root root 0 Dec 6 2024 file_6 -rw-r--r--. 1 root root 0 Dec 7 2024 file_7 -rw-r--r--. 1 root root 0 Dec 8 2024 file_8 -rw-r--r--. 1 root root 0 Dec 9 2024 file_9
2. 削除対象ファイルの確認
今回は、オプション「-newermt」と日時を指定します。
日時指定のややこしいポイントなのですが、「! -newermt」が指定した日時を含まずに検索されるのに対して、「-newermt」の場合は指定した日時を含んで検索されます。
ですので、 2024/12/5 より後に更新されたファイルを削除する場合は、 2024/12/6 を指定しないとダメです。ややこしい。
そして、先程同様 rm ではなく ls を指定しコマンドを実行してみます。
ls しますか?と聞かれるので「y」を打ち込むと削除対象のファイルが表示されます。
2024/12/6 ~ 12/9 に更新されたファイル(file_6 ~ file_9)が検索出来ていることが確認できます。
[root@localhost ~]# find /var/log/test_log -type f -newermt 'Dec 6 2024' | xargs -p ls ls /var/log/test_log/file_6 /var/log/test_log/file_7 /var/log/test_log/file_8 /var/log/test_log/file_9?...y /var/log/test_log/file_6 /var/log/test_log/file_7 /var/log/test_log/file_8 /var/log/test_log/file_9
3. ファイルの削除
では消します。
ls を rm に変えてコマンドを実行し、rm しますか?と聞かれるので、「y」を打ち込みます。
[root@localhost ~]# find /var/log/test_log -type f -newermt 'Dec 6 2024' | xargs -p rm rm /var/log/test_log/file_6 /var/log/test_log/file_7 /var/log/test_log/file_8 /var/log/test_log/file_9?...y
4. ファイルを確認
2024/12/5 より後に作成したファイルが消えていることが確認できます。
[root@localhost test_log]# ll /var/log/test_log total 0 -rw-r--r--. 1 root root 0 Dec 1 2024 file_1 -rw-r--r--. 1 root root 0 Dec 2 2024 file_2 -rw-r--r--. 1 root root 0 Dec 3 2024 file_3 -rw-r--r--. 1 root root 0 Dec 4 2024 file_4 -rw-r--r--. 1 root root 0 Dec 5 2024 file_5
おまけ:もう少し細かく指定したい
いちいち手順を書いていたら長くなりすぎたのでもうやめておきます。
最後に、指定した日時のファイルのみを削除するコマンドも紹介したいです。
先程同様下記のようなファイルがあるとして、12/3~12/7 だけ消したいな~と思うとします。
[root@localhost test_log]# ll /var/log/test_log total 0 -rw-r--r--. 1 root root 0 Dec 1 2024 file_1 -rw-r--r--. 1 root root 0 Dec 2 2024 file_2 -rw-r--r--. 1 root root 0 Dec 3 2024 file_3 -rw-r--r--. 1 root root 0 Dec 4 2024 file_4 -rw-r--r--. 1 root root 0 Dec 5 2024 file_5 -rw-r--r--. 1 root root 0 Dec 6 2024 file_6 -rw-r--r--. 1 root root 0 Dec 7 2024 file_7 -rw-r--r--. 1 root root 0 Dec 8 2024 file_8 -rw-r--r--. 1 root root 0 Dec 9 2024 file_9
さっきまでの要領で「-newermt」オプションを使って「-newermt "Dec 3 2024" ! -newermt "Dec 8 2024"」といった風に指定できます。少し自由度の高い指定の仕方ができるので、これも使えそうです。
ご参考までに!
[root@localhost test_log]# find /var/log/test_log -type f -newermt "Dec 3 2024" ! -newermt "Dec 8 2024" | xargs -p rm rm /var/log/test_log/file_5 /var/log/test_log/file_3 /var/log/test_log/file_4 /var/log/test_log/file_6 /var/log/test_log/file_7?...y [root@localhost test_log]# ll /var/log/test_log total 0 -rw-r--r--. 1 root root 0 Dec 1 2024 file_1 -rw-r--r--. 1 root root 0 Dec 2 2024 file_2 -rw-r--r--. 1 root root 0 Dec 8 2024 file_8 -rw-r--r--. 1 root root 0 Dec 9 2024 file_9
まとめ
いかがでしたでしょうか。
今回は find コマンドでのファイル削除にフォーカスした内容でしたが、もっといろいろな用途で便利に使えるコマンドですので、使いこなせるよう引き続き勉強していきます🔥
最後までご覧いただきありがとうございます!
参考サイト:
findコマンドとは?Linuxコマンドでファイルやディレクトリを検索する方法をご紹介
findコマンドの使い方を簡単に理解するための7つのルール+実践的な知識
find -exec と find | xargs との違い