特定のサブディレクトリを除くすべてのファイルを削除するには、検索を使用します。

特定のサブディレクトリを除くすべてのファイルを削除するには、検索を使用します。

aサブフォルダ内のすべてのファイルを除いて、特定の期間にフォルダにアクセスしなかったすべてのファイルを繰り返し削除したいと思いますb

find a \( -name b -prune \) -o -type f -delete

ただし、エラーメッセージが表示されます。

find:-delete操作は自動的に-deepを有効にしますが、-pruneは-deepが適用されている間は何もしません。続行するには、-lengthオプションを明示的に使用してください。

-depth追加すると、すべてのファイルが含まれます。bいいえ発生する。

これを行う安全な方法を知っている人はいますか?

ベストアンサー1

1つの方法は-exec rm代わりに使用することです-delete

find a \( -name b -prune \) -o -type f -exec rm {} +

または-not -path代わりに使用してください-prune

find a -not -path "*/b*" -type f -delete

なぜ-prune以下と競合するのかを説明してください-delete

ヒントを与えて作成することはうまくいかないので、withを使用しようとすると-delete苦情がわかります。-prune-delete-depth-depth-prune

以下を使用または使用せずに find 動作を観察します-depth

$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2

単一のディレクトリ内の順序は保証されません。ただし、ディレクトリはコンテンツの前に処理されます。foo/beforefoo/*foo/barbeforeを参照してくださいfoo/bar/*

これは元に戻すことができます-depth

$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/

現在がfoo/*beforeの前に来ていることに注意してくださいfoo/。と同じですfoo/bar

さらなる説明:

  • -prunefind がディレクトリに降りるのを防ぎます。つまり、-pruneディレクトリの内容をスキップします。あなたの場合、-name b -pruneこれは、 find がその名前のディレクトリに到達すると、すべてのbサブディレクトリを含むそのディレクトリをスキップすることを意味します。
  • -depthfindにディレクトリ自体の前にディレクトリの内容を処理させます。これは、findがディレクトリエントリの処理を開始したときにbその内容がすでに処理されていることを意味します。したがって、-prune無効で-depth有効です。
  • -deleteつまり、-depthコンテンツを最初に削除してから空のディレクトリを削除できます。-delete空でないディレクトリの削除を拒否します。

代替方法の説明:

find a -not -path "*/b*" -type f -delete

覚えやすく、そうでないかもしれません。

コマンドはまだディレクトリに入り、bその中にあるすべてのファイルを処理しますが、拒否します-not。ディレクトリが大きいと、bパフォーマンスの問題が発生する可能性があります。

-path別の方法で動作します-name。フルパス-nameではなく(ファイルまたはディレクトリの)名前のみが一致します。-pathたとえば、パスを観察してみてください/home/lesmana/foo/bar-name bar名前があるので一致しますbar-path "*/foo*"文字列/fooがパスにあるので一致します。-path使用する前に理解する必要がある複雑さがいくつかあります。詳しくはマニュアルページをご覧くださいfind

これが100%完璧ではないことに注意してください。 「誤検知」の可能性があります。上記のコマンドが作成された方法は、名前がb(正数)で始まる親ディレクトリを持つすべてのファイルをスキップします。しかし、ツリーの場所に関係なく、名前で始まるすべてのファイルをスキップしますb(誤検出)。これは、より良い表現を書くことで解決できます"*/b*"。これは読者に練習問題として残す。

私はあなたがaandをbプレースホルダとして使用しており、実際の名前はallosaurusandに近いと仮定しますbrachiosaurus。これを置き換えると、誤brachiosaurus検出bの数が大幅に減少します。

少なくとも偽の肯定は次のとおりです。いいえあまりにも悲惨でないように削除しました。また、最初にコマンドなしでコマンドを実行し-delete(暗黙的なコマンドを入力する必要があります-depth)、出力を調べて誤検出を確認することもできます。

find a -not -path "*/b*" -type f -depth

おすすめ記事