次にリストされているパスのファイルを除いて、ディレクトリ内のすべてのファイルを削除します。

次にリストされているパスのファイルを除いて、ディレクトリ内のすべてのファイルを削除します。

次のファイルが提供されます。

data/A/a.txt
data/B/b.pdf
...
date/P/whatever.log
...
data/Z/z.jpg

data/A/、、data/B/...data/Z/ディレクトリ内のすべてのファイルを削除したいと思います。とは別にファイルにリストされているディレクトリの1つの下にあるファイルdata/dont_clean.txt。たとえば、リストした場合、data/P以下data/dont_clean.txtには何も触れないでくださいdata/P/

それは次のとおりです。

find data/ -mindepth 2 -maxdepth 2 -type f -not -path {listed in data/dont_clean} -delete

もちろん、これは有効なコマンドではありません。

私が試したバリエーション

find data/ -mindepth 2 -maxdepth 2 -type f -exec grep data/dont_clean.txt '{}' \;

しかし、ちょうど間違ったコマンドを生成したのか、私が実行した出力を得たのかわかりません。

Ubuntu 12.10でbashを使用しています

ベストアンサー1

以下は大まかにテストしたコードですが、方法を教えてもらうことができます。次のファイルがあるとしますignore.txt

1/
2/

サンプル

次のファイルを含むサンプルディレクトリがあります。

$ mkdir -p dirs/{1..5}
$ touch dirs/{1..5}/afile

結果は次のとおりです。

$ tree dirs/
dirs/
|-- 1
|   `-- afile
|-- 2
|   `-- afile
|-- 3
|   `-- afile
|-- 4
|   `-- afile
`-- 5
    `-- afile

実行例

このツリーに対してこのコマンドを実行すると、次のようになります。

$ find dirs/ -type f -print0 | fgrep -zFvf ./ignore.txt
dirs/5/afiledirs/4/afiledirs/3/afile

にリストされていないディレクトリのファイルだけがインポートされていることがわかりますignore.txt

したがって、rm除外されていないファイルを削除するために最後に1つを追加できます。

$ find dirs/ -type f -print0 | fgrep -zFvf ./ignore.txt | xargs -0 rm -f

調べてみるとうまくいくのがわかります。

$ tree dirs/
dirs/
|-- 1
|   `-- afile
|-- 2
|   `-- afile
|-- 3
|-- 4
`-- 5

解決が必要な問題

このアプローチの大きな問題は、ファイル内の文字列がignore.txtディレクトリ構造の他の部分と一致する可能性があることです。したがって、このファイルの文字列が期待どおりに一意であることを確認するために注意を払う必要があります。

ロープの周りにいくつかのバリアを配置することで、ロープを保護するためにロープの最初または最後に固定できます。

詳細

上記のコマンドは次のことを行います。

  1. ディレクトリ内のすべてのファイルを探すdirs
  2. igonre.txtファイルが存在するディレクトリ内のすべてのファイルをフィルタリングします。
  3. フィルタリストをコマンドxargsに渡すrm -f

おすすめ記事