特定の名前のフォルダーを除くフォルダー内のすべてのフォルダーを削除する


17

毎日のスクリプトを使用して、フォルダー内のすべてのフォルダーを削除する必要があります。その日のフォルダは残す必要があります。

フォルダ「myfolder」には3つのサブフォルダがあります:「test1」、「test2」、「test3」「test2」以外のすべてを削除する必要があります。

ここで正確な名前に一致させようとしています:

find /home/myfolder -type d ! -name 'test2' | xargs rm -rf

または

find /home/myfolder -type d ! -name 'test2' -delete

このコマンドは常にメインフォルダー「myfolder」も削除しようとします!これを回避する方法はありますか?


6
UnixおよびLinuxでは、これらを「フォルダ」ではなく「ディレクトリ」と呼びます。
-tchrist

1
シェルに応じて、その!演算子を引用する必要がある場合があります:\!または'!'
トビースパイト

回答:


32

これ./myfolderにより./myfolder/test2、それ以外のすべてのフォルダーが削除され、そのすべてのコンテンツが保持されます。

find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?' -delete

使い方

  • find 検索コマンドを開始します。
  • ./myfolderディレクトリ./myfolderとそのコンテンツで開始するようにfindに指示します。

  • -mindepth 1./myfolder自分自身 に一致するのではなく、その下のファイルとディレクトリだけに一致します。

  • ! -regex '^./myfolder/test2\(/.*\)?'!正規表現に一致するファイルまたはディレクトリをexclude()除外するように指示します^./myfolder/test2\(/.*\)?^パス名の先頭と一致します。この表現は (/.*\)?、(a)スラッシュの後に何かが続くか、または(b)まったく何もないかのいずれかに一致します。

  • -delete 一致する(つまり、除外されない)ファイルを削除するようにfindに指示します。

次のようなディレクトリ構造を考えます。

$ find ./myfolder
./myfolder
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2

findコマンドを(なしで-delete)実行して、一致するものを確認できます。

$ find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?'
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3

残っているファイルを調べることで、これが機能したことを確認できます。

$ find ./myfolder
./myfolder
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2

1
サブディレクトリ-pruneをそのままにする代わりにtest2/*/:に戻ってrm -r追加し-maxdepth 1ます。
トビースパイト

@Isaac OK。できた (また、あなたの優れた答えのために+1。)
ジョン1024年

すばらしい仕事です!しかし、申し訳ありません:それは内のすべてのファイルを削除します./myfolder。あなたは、不足している(IMvhO)を必要とする-type dためにディレクトリのみ
アイザック

OK、これはあなたが望むように動作するはずです:find ./myfolder -depth -mindepth 1 -maxdepth 1 -type d ! -regex '^./myfolder/test2\(/.*\)?'
Isaac

10

bashの使用

shopt -s extglob
rm -r myfolder/!(test2)/

例:

$ tree myfolder/
myfolder/
├── test1
│   └── file1
├── test2
│   └── file2
└── test3
    └── file3

$ echo rm -r myfolder/!(test2)
rm -r myfolder/test1 myfolder/test3
$ rm -r myfolder/!(test2)
$ tree myfolder/
myfolder/
└── test2
    └── file2

1 directory, 1 file

5

tl; dr

find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 \
     -exec echo rm -rf '{}' \;

ファイルのリストに満足したら、エコーを削除します。


を使用-mindepth 1すると、最上位ディレクトリが選択されないことが保証されます。

$ find ./myfolder -mindepth 1 -type d
./myfolder/test2
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3

しかし-not -name test2ますない内部のサブディレクトリを避けますtest2

$ find ./myfolder -mindepth 1 -type d -not -name 'test2'
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3

そのためには、プルーンのようなものが必要です。

$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3

ただしdelete、を使用しないでくださいdepth

$ find ./myfolder -depth -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test/a1/a2/a3
./myfolder/test/a1/a2
./myfolder/test/a1
./myfolder/test

どちらかを使用しますrm -rfecho実際に消去する場合は削除します):

$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
rm -rf ./myfolder/test/a1
rm -rf ./myfolder/test/a1/a2
rm -rf ./myfolder/test/a1/a2/a3

または、必要なのがディレクトリ(およびその中のすべて)を削除するだけである場合使用maxdepthします(echo実際に消去するにはを削除します)。

$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test

-deleteディレクトリが空でない場合、A は引き続き失敗します。

$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -delete
find: cannot delete ‘./myfolder/test’: Directory not empty

2

zshを使用している場合、次のことができます。

setopt extended_glob # if you don't have it enabled

rm -rf myfolder/^test2

0

以下のコマンドでテストし、正常に動作しました

find  /home/myfolder -maxdepth 1 -type d ! -iname test2 -exec rm -rvf {} \;

OPと同じ問題に遭遇しました。/ home / folderをコマンドラインに(criticalなしで-mindepth 1)リストすると、その最上位ディレクトリがすべての基準(ディレクトリであり、「test2」という名前ではない)に一致するため、削除されます。
ジェフシャラー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.