find コマンドの問題 - デフォルトのディレクトリを一覧表示せずにディレクトリの下のサブディレクトリとファイルを一覧表示する方法

find コマンドの問題 - デフォルトのディレクトリを一覧表示せずにディレクトリの下のサブディレクトリとファイルを一覧表示する方法

検索コマンド - 引数として渡されたデフォルトディレクトリを一覧表示せずに、ディレクトリの下にあるサブディレクトリとファイルのみを一覧表示する方法。

例:

find /abc/def/ghi -mtime +10 

上記のコマンド出力の結果には、デフォルトディレクトリがその中にあるサブディレクトリとファイルとともに一覧表示されます。

/abc/def/ghi 
/abc/def/ghi/fff
/abc/def/ghi/abc.txt

出力が以下のようになります。

/abc/def/ghi/fff
/abc/def/ghi/abc.txt

この問題の原因は、findコマンド出力がディレクトリとファイルを繰り返し削除するために使用されるためです。したがって、デフォルトのディレクトリが/abc/def/ghi10日間使用されない場合、そのディレクトリも一覧表示され、最終的に削除されます。

find /abc/def/ghi -mtime +10 -exec rm -rf {} \;

答え1

しきい値より古いファイルを見つけて、空のディレクトリを削除します。

この$base変数は4回(1文あたり2回)使用されます。これにより、私たちは自己-path "$base/*"削除を防ぐことができます。つまり、最上位または 。$base*...

base=/abc/def
find "$base/" -path "$base/*" -type f -mtime +10 -exec rm -f {} +
find "$base/" -depth -path "$base/*" -type d -exec rmdir {} + 2>/dev/null

答え2

find2つの方法で、最上位の検索パスを明示的に無視するように要求できます。

  1. -path最上位の検索パスで作業したくない場合は、標準テストを使用してください。

    find /abc/def/ghi ! -path /abc/def/ghi ...other tests/actions...
    

    これにより、最上位の検索パスが検出されますが、-pathテストに使用されたパス名と正確に一致するため、そのパスを操作しないでください。これは! テスト目的に反します。

  2. 非標準ですが、一般的に実装されている-mindepthテストを使用してください。

    find /abc/def/ghi -mindepth 1 ...other tests/actions...
    

    これにより、find「深さ0」のすべてのパス名、つまり最上位の検索パス自体が無視されます。

  3. 実際にやろうとしている3番目のアプローチは、ディレクトリに興味を持たないことです(トップレベルの検索パスは通常ディレクトリパスなので)。

    find /abc/def/ghi ! -type d ...other tests/actions...
    

今やるべきことを見てみると、過去10日間に新しいコンテンツが追加または削除されていないディレクトリをクリーンアップしたいようです。最も安全な方法は直接見ることです。文書特に古いファイルを削除してください。これを完了すると、最終的に空のディレクトリを削除できます。

ディレクトリのタイムスタンプに依存したくない理由は、そのタイムスタンプがファイルがいつ入ったかを知らせないからです。 サブディレクトリ追加または削除できます。古いタイムスタンプのためにディレクトリを削除すると、サブディレクトリの新しいファイルが誤って削除される可能性があります。

私は次のようなものを使用できます

find /abc/def/ghi -type f -mtime +10 -delete
find /abc/def/ghi ! -path /abc/def/ghi -type d -empty -delete

! -path /abc/def/ghi空の場合、削除に同意すると、最上位の検索パスを削除できます。

-emptyテストと-deleteタスクは非標準なので、標準を使用して同じタスクを実行する方法は次のとおりですfind

find /abc/def/ghi -type f -mtime +10 -exec rm -f {} +
find /abc/def/ghi -depth ! -path /abc/def/ghi -type d -exec rmdir {} \; 2>/dev/null

最初のコマンドは簡単でなければなりません。古いファイルを収集し、rm -f一括して読み込みます。

2番目のコマンドは、-depth深さ優先検索を実行するために使用されます。私たちがこれをする理由は

  1. find削除したばかりのディレクトリに入れたくありません。
  2. ディレクトリは次のことができます。~になるその中の他のディレクトリを削除すると空でした。

2番目のコマンドもrmdir実行しようとします。みんなディレクトリ(最上位検索パスを除く)これ失敗する空でないディレクトリの場合は、エラーストリームをリダイレクトして/dev/null診断メッセージを無視します。

完全に空のディレクトリのみを呼び出すには、rmdir次を使用できます。

find /abc/def/ghi -depth ! -path /abc/def/ghi -type d \
    -exec bash -O dotglob -O nullglob -c '
    for dirpath do
        set -- "$dirpath"/*
        [ "$#" -gt 0 ] && rmdir "$dirpath"
    done' bash {} +

bashこれはディレクトリを繰り返し、各ディレクトリに対してその*中のワイルドカードパターンを拡張しようとする短いインラインスクリプトを呼び出します。名前がまったくない状態に拡張されると、ディレクトリは削除されます。

答え3

気にしないでください。ほとんど試行錯誤なしに答えを自分で見つけました。

find /abc/def/ghi/* -mtime +10 -exec rm -rf {} \;

関連情報