Linux findコマンドを使ってn日前のファイルを削除する 3つの記述方法
2019/06/18
Linux findコマンドを使ってn日前のファイルを削除する 3つの記述方法
findコマンドを使ってn日前のファイルを削除する 3つの記述方法
「/var/www/html/」フォルダの中にあるファイルのうち、タイムスタンプが 6日以上前のファイルを削除するコマンドの記述方法は、下記の 3つの記述方法があります。
-execオプションを使う方法
1 |
$ find /var/www/html/ -mtime +5 -exec rm -f {} \; |
xargsコマンドを使う方法
1 |
$ find /var/www/html/ -mtime +5 | xargs rm |
-deleteオプションを使う方法
1 |
$ find /var/www/html/ -mtime +5 -delete |
findコマンドを使ってn日前のファイルを削除する記述方法の解説
findコマンドの基本形
findコマンドは、ファイルを探すときに使うコマンドで、基本形は以下になります。
1 |
find [path...] [expression] |
findコマンドに日付を指定するオプション
1 |
$ find /var/www/html/ -mtime +5 |
findコマンドの基本形に対して、日付を指定してファイルを探すコマンドの記述方法の一つの例が上記になります。
この例では「-mtime +5
」の部分が日付を指定するオプションになります。
-mtime +n
「+」が付く場合は、n日前以前((n+1)日より古い。24時間×(n+1)日より過去)のファイル、フォルダを対象に検索します。
-mtime -n
「-」が付く場合は、n日前以降(n日より新しい。24時間×n日から現在まで)のファイル、フォルダを対象に検索します。
-mtime n
「+」も「-」付かない場合は、n日前(24時間×n日~24時間×(n+1)日の間)のファイル、フォルダを対象に検索します。
-mmin +n
「-mtime」オプションは「n日」ですが、「-mtime」の代わりに「-mmin」を指定することで、「n分」を指定することができます。
n日に小数点を指定することもできる
下記のように「-mtime」のパラメーターとして「-0.5」のように整数ではなく小数を指定することもできます。
1 |
$find /var/www/html/ -mtime -0.5 |
この場合は、12時間前から現在までのものが対象になります。
-daystartオプションで基準を 0時に
「-daystart」オプションを付けない記述の場合は、コマンドを実行した日時を基準として、n日前を判定します。
ですが、「-daystart」オプションを付けた場合は、コマンドを実行した n日前の 0時が基準となります。
1 |
$ find /var/www/html/ -daystart -mtime 3 |
「2019年02月10日 10:00:00」に実行した場合、「2019年02月10日 00:00:00 ~ 2019年02月11日 00:00:00」が対象になります。
(「2019年02月10日 23:59:59」までではないようです。)
Linuxのタイムスタンプは「mtime」「ctime」「atime」の 3種類ある
先に書いたコマンドのオプションとして指定している「-mtime」「-mmin」は、Linuxのタイムスタンプの一つである「mtime」の日時を見て判断します、というオプションです。
ですが、Linuxのファイルのタイムスタンプには「mtime」「ctime」「atime」の 3つがあります。
「mtime」が一般的なファイルの更新日時になりますが、「ctime」「atime」を条件と指定したい場合は、同様に「-ctime」「-atime」「-cmin」「-amin」をオプションとして指定することができます。
Linuxのタイムスタンプに関しては、下記の記事で詳しく解説していますので参考にしてください。
Linuxのタイムスタンプはmtime、ctime、atimeの3種類。touchコマンドで更新する方法
findコマンドの条件を設定するその他のオプション
1 |
$ find /var/www/html/ -mtime +5 |
上記のコマンドは、5日前のファイルを削除する、という条件ですが、加えて、「.log」が付くログファイルだけ削除したい、「.gitkeep」ファイルは削除したくない、といった条件が必要な場合もあるでしょう。
そんなときは、下記のように指定します。
-nameオプションでファイル名を指定する
「-name」オプションで該当する名前を追加します。
「*.log」のように正規表現を利用した記述も可能です。
1 |
$ find /var/www/html/ -mtime +5 -name "*.log" |
! -nameオプションでファイル名を対象外にする
「-name」オプションを使うと、該当する名前のファイルが対象になりますが、ファイルの名前が含まれているものを除外したいときは「!」「-not」オプションを追加します。
1 2 |
$ find /var/www/html/ -mtime +5 ! -name ".gitkeep" $ find /var/www/html/ -mtime +5 -not -name ".gitkeep" |
「!」でも「-not」でも動作は同じです。
「-name」「! -name」オプションを組み合わせる
ありそうな条件が思い浮かびませんが、ファイル名に「e」が含まれるファイルのうち、「.gitkeep」ファイルは除外したい場合は、以下のように記述します。
1 2 |
$ find /var/www/html/ -mtime +5 -name "*e*" ! -name ".gitkeep" $ find /var/www/html/ -mtime +5 -name "*e*" -not -name ".gitkeep" |
「-type」オプションでファイルとフォルダを区別する
findコマンドを実行する対象のフォルダの中にファイルもフォルダもある場合、ファイルだけを選択したい、フォルダだけを選択したい、という場合もあるでしょう。
そんなときは、「-type」オプションでファイル、フォルダを区別することができます。
「-type」オプションに「f」を付与するとファイルが選択されます。
1 |
$ find /var/www/html/ -mtime +5 -type f |
「-type」オプションに「d」を付与するとフォルダ(ディレクトリ)が選択されます。
1 |
$ find /var/www/html/ -mtime +5 -type d |
findで見つかったファイルに対して処理を実行する -execオプション
1 |
$ find /var/www/html/ -mtime +5 -exec rm -f {} \; |
この例の「-exec rm -f {} \;
」の部分が、findで見つかったファイルを削除する、という処理の部分です。
findコマンドで見つかったファイル、フォルダに対して何かしらの処理を実行するオプションが「-exec」になります。
「-exec」オプションの標準形
1 |
-exec [command] {} \; |
上記が「-exec」オプションの標準形です。
-exec rm -f {} \;
の解説
「-exec rm -f {} \;
」の場合は
「-exec」オプションで実行するコマンドが「rm」(ファイル、フォルダを削除)ということです。
(rmコマンドの -fオプションは、エラーメッセージを表示しないためのオプションですが、私の CentOS環境では -fオプションに関係なくエラーメッセージが出ていました。)
また、「{}」は、findコマンドで見つかったファイルを「[command]」で実行する際のパラメーターにする、という意味です。
「\;」は、-execオプションがここで終わりますよ、という意味の記述です。
-execオプションでフォルダを削除する場合
「-exec rm -f {} \;
」
では、フォルダは削除できませんが、
「-exec rm -r {} \;
」
とすることでフォルダも削除することができるようになります。
「rm」コマンドの「-r」オプションがフォルダも削除するオプションになります。
-execオプションのコマンドに「ls -l」を指定する
findコマンドで該当したファイルの一覧を、ls -lコマンドでファイルの詳細情報を表示する場合は
1 |
$ find /var/www/html/ -mtime +5 -exec ls -l {} \; |
のように、「-exec ls -l {} \;
」とすることで対応が可能です。
xargsコマンドで findコマンドで取得したファイルリストを削除する
xargsコマンドは、「標準入力やファイルからリストを読み込みコマンドラインを作成して実行する」コマンドです。
これだけ読んでもよく分かりませんが、下記のように記述して、findコマンドで取得したファイルのリストを「|(パイプ)」で xargsコマンドに取り込み「rm」コマンドのパラメーターとして利用する、といった使い方ができます。
1 |
$ find /var/www/html/ -mtime +5 | xargs rm |
つまり、「-exec」オプションで実行する下記の部分を
1 |
-exec [command] {} \; |
「xargs」コマンドでは下記のように記述する、ということになります。
1 |
| xargs [command] |
当然ながら、「rm」コマンドにはオプションも設定することができ、下記のようにすればフォルダも含めて削除することができます。
1 |
$ find /var/www/html/ -mtime +5 | xargs rm -r |
findで見つかったファイルを削除する -deleteオプション
実は、findコマンドには、「-exec」オプションや「xargs」コマンドを組み合わせることなく、簡単に削除するオプション「-delete」オプションが用意されています。
1 |
$ find /var/www/html/ -mtime +5 -delete |
上記のように「-delete」オプションを加えるだけで、findで対象になったファイルを削除する事ができます。
また、「-delete」オプションは、フォルダの中身が空の場合はフォルダも削除してしまいます。(フォルダが空ではない場合は、エラーメッセージが表示され、削除されません。)
ただ、「-delete」オプションは OSによっては使えない可能性があるようです。
もともとは、BSD系のオプションだったようですが、私の環境の CentOS7では動作しました。
-execオプション、xargsコマンド、-deleteオプションの違い
「-execオプション」と「xargsコマンド」の違いは、実行スピードです。
findコマンドで取得したファイルが、下記だったとします。
test1.txt
test2.txt
test3.txt
「-execオプション」は、下記のように処理をします。
rm test1.txt
rm test2.txt
rm test3.txt
対して、「xargsコマンド」は、下記のように処理をします。
rm test1.txt test2.txt test3.txt
複数回の rmコマンドを実行する「-execオプション」より、まとめて 1回で処理する「xargsコマンド」の方が高速に処理できるのです。
そのため、削除するファイルの数が多い場合は、積極的に「xargsコマンド」を使うほうがよさそうです。
また、「-delete」コマンドのスピードはよく分かりませんが、削除する処理に対して細かなオプションを指定する必要がない場合は、簡潔に記述できる良さがあります。
コマンドを実行する際の注意点
今回紹介しているコマンドですが、ファイルを削除するコマンドになります。
そのため、いきなり使ってみるのではなく、何度も実験をして、確実な確認をしてから実行してください。
実験をする際は、「-exec」以降を削除して、下記の部分だけを実行して、ファイルのリストを作成してみるといいでしょう。
1 |
$ find /var/www/html/ -mtime +5 |
出力されるファイルのリストが想定通りか、を確認してからファイルを削除するオプションを追加しましょう。
また、「-exec」オプションを追加する際も、「ls -l」コマンドを追加してみるなど、万一の場合でも不具合が生じにくいコマンドで実験することをおすすめします。
実験用のファイル、フォルダを作る場合は touchコマンドを使う
今回はファイルの更新日付を基準に findコマンドでファイルを抽出します。
その実験する際にファイルの更新日付を指定した日時に変更する必要がありますが、その場合は「touch」コマンドを使います。
1 |
$ touch -d "2019/01/01 12:00:00" file.txt |
下記のように、「-d "2019/01/01 12:00:00"
」の部分を記述しないと、現在の日時の更新日付になります。
1 |
$ touch file.txt |
Linuxにおけるファイルのタイムスタンプ(mtime、ctime、atimeの 3つある)と、そのタイムスタンプを更新するコマンド「touch」の詳しい解説は下記を参照してください。
Linuxのタイムスタンプはmtime、ctime、atimeの3種類。touchコマンドで更新する方法
cronで自動実行する際にログも出力する方法 2019.06.18追記
コマンドを入力して実行する場合は、これまでに説明した内容で問題ないでしょう。
ファイルの削除が実行されれば削除したファイルのリストが表示されますので、確認ができます。
ですが、cronで自動実行する場合には実行された処理(削除されたファイル)をログとして出力しないと処理が実行されたのか確認できないため、ログ出力の方法について改めて確認しました。
その結果、私は下記の構文を採用することにしました。
1 2 |
# Delete TemporaryFiles AdWords-Download 55 23 * * 1 find /var/www/html/ -mtime +6 -not -name ".gitkeep" -type f | xargs rm -v >> /var/www/logs/delete.log 2>&1 | date >> /var/www/logs/delete.log |
この構文であれば、実行した日時が出力された後、削除したログが出力されます。
cronでログを出力する方法に関する実験の数々
先の構文に行き着くまでにいくつかの構文についても実験を行いました。
その結果、利用するコマンドによっては削除したファイルが取得できない場合もありました。
具体的には下記のようになります。
1 2 3 4 5 |
55 23 * * * find /var/www/html/ -mtime +60 -not -name ".gitkeep" -type f -delete >> /var/www/logs/delete.log 2>&1 55 23 * * * find /var/www/html/ -mtime +60 -not -name ".gitkeep" -type f | xargs rm >> /var/www/logs/delete.log 2>&1 55 23 * * * find /var/www/html/ -mtime +60 -not -name ".gitkeep" -type f -exec rm -f {} \; >> /var/www/logs/delete.log 2>&1 |
crontabに上記のように設定した場合は、正常に処理が実行されたときはいずれもログが出力されませんでしたので、ログファイルの出力処理を記述しても意味がありませんでした。
唯一「xargs rm」の処理の場合は、削除対象ファイルがない場合、下記のエラーが出力されました。
1 2 |
rm: オペランドがありません Try 'rm --help' for more information. |
また、更に下記のような構文を実験しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
※下記の構文では、対象ファイルがない場合は何も出力されません。 55 23 * * * find /var/www/html/ -mtime +60 -not -name ".gitkeep" -type f | tee -a /var/www/logs/delete.log | xargs rm ※下記の構文では、削除対象ファイルがない場合は「rm: オペランドがありません」が出力されます。 ファイルを削除した場合は、「removed ****」「****を削除しました」が付きます。 55 23 * * * find /var/www/html/ -mtime +60 -not -name ".gitkeep" -type f | xargs rm -v >> /var/www/logs/delete.log 2>&1 ※下記の構文では、これは削除対象ファイルがない場合は「rm: オペランドがありません」が出力されます。 55 23 * * * find /var/www/html/ -mtime +60 -not -name ".gitkeep" -type f | xargs -t rm >> /var/www/logs/delete.log 2>&1 ※下記の構文では、対象ファイルがない場合は何も出力されません。 ファイルを削除した場合は、「removed ****」「****を削除しました」が付きます。 55 23 * * * find /var/www/html/ -mtime +60 -not -name ".gitkeep" -type f -exec rm -v -f {} \; >> /var/www/logs/delete.log 2>&1 ※下記の構文では、対象ファイルがない場合は何も出力されません。 55 23 * * * find /var/www/html/ -mtime +60 -not -name ".gitkeep" -type f -print -delete >> /var/www/logs/delete.log 2>&1 ↑対象ファイルがない場合は何も出力されない ※下記の構文にすると、実行した日時を追記することができます。 ですが、「| date >> /var/...」を先に書くと「削除しました」の後ろに日付が追記されてしまいます。 55 23 * * * find /var/www/html/ -mtime +60 -not -name ".gitkeep" -type f | xargs rm -v >> /var/www/logs/delete.log | date >> /var/www/logs/delete.log 2>&1 |
その結果、先に示した構文が一番よろしかろう、という結論にいたり、それを採用することにしました。
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
UNIX・Linuxの sedコマンドで特定の文字列を置換する方法
UNIX・Linuxのコマンドで特定の文字列を置換する sedコマンドの使い方と、perlコマンドを使っての方法を解説しています。
-
less、moreはページャー、ファイルの中身を表示するLinuxのコマンド
Linuxにはコマンドで実行した結果が長い場合、1画面ごとに区切って表示するコマンドが用意されている。それがページャーと呼ばれるmore、lessだ。この使い方を解説。
-
Linuxのbashのコマンドの履歴をhistoryで確認し!、↓、↑で実行する
Linuxで実行したコマンドの履歴を確認するコマンド「history」。「history」の使い方、設定の変更、設定ファイルの設置場所について解説。「!番号」「!文字列」「!?文字列」など。
-
Linuxでファイルの内容を表示するcatコマンドの解説。more、lessで代替も
catはLinuxのコマンドで、本来の機能はファイルを連結だが、ファイルの内容を表示する機能のために使うことが多く使用頻度が高い。同種の機能のmore、less、tacコマンドについても解説。
-
cat、less、head、tail、split、sedなどLinuxでファイル、文字列を操作するコマンド
Linuxでファイル、テキストを操作するコマンドのまとめ。cat、less、head、tail、split、tr、sedなど、ファイルを表示、置換、連結、分割などの各コマンドの使い方の紹介と詳細ページの紹介。
-
Linuxの wcコマンドでファイルの行数、単語数、バイト数、文字数をカウントする
Linuxの行数、単語数、文字数、バイト数をカウントする「wc」コマンドの使い方の解説。find、lsと組み合わせてファイル数のカウント方法などを解説。
-
Linuxのnlは行番号を付与してファイルの内容を表示するコマンド
Linuxでファイルを表示する際に行番号を付与するにはcatコマンドにnオプションを使うことでも可能。しかし、行番号を付与する専門のnlコマンドがある。ここではその使い方を詳細に解説。
-
makewhatis、mandbコマンドでLinuxのオンラインマニュアル索引情報を更新
Linuxコマンドのオンラインマニュアルを検索するwhatis、aproposなどのコマンドはwhatisデータベースを対象に検索する。このデータベースを更新するmandb、makewhatisコマンドを解説。
-
Linuxのコマンドの情報を調べるwhich、whereis、whatis、apropos、man
Linuxのコマンドの実行ファイルやマニュアルの情報を確認するコマンドwhich、whereis、whatis、apropos、manの機能と使い方、似たところと違うところの紹介。
-
Linuxの環境変数でパスの設定をする方法とシェル変数の扱い方を解説
Linuxでコマンドを設置するパスの設定情報である環境変数「PATH」の確認方法と環境変数「PATH」に新しいパスを追加する方法の解説。Linuxのシェルでの変数の扱い方についての解説も。
Comment
ubuntu serverでNASを構築する際の参考になりました。
具体的にやろうと思っていることですが、毎日定時にスナップショットを
した後に、定期的に過去のフォルダを削除するというような使い方をしようと思っています。
この記事を参考にチャレンジしてみます。
La さん、コメントありがとうございます。
お役に立てて良かったです。
頑張ってください。上手くいくことを祈っています!