コマンドラインを使用して、指定されたファイル/フォルダーを除くすべてのファイルを削除しますか?

コマンドラインを使用して、指定されたファイル/フォルダーを除くすべてのファイルを削除しますか?

次のような構造を持つ多数のフォルダーとさまざまなファイルを含むフォルダーがあります。

NASA
├── a
│   ├── doc1
│   ├── doc2
│   ├── doc3
│   ├── folder1
│   └── folder2
├── b
│   ├── doc1
│   ├── doc2
│   ├── doc3
│   ├── folder1
│   └── folder2
├── c
│   ├── doc1
│   ├── doc2
│   ├── doc3
│   ├── folder1
│   └── folder2
├─ x
├─ y
└─ z     

NASA/指定したフォルダとファイル以外のフォルダ( )の内容を削除したい。

たとえば、aフォルダー、bフォルダー、xファイルを保持したいとします。

私は試したこの解決策 :

 rm !(a/) -r NASA/

そして(回答で説明したようにここ):

find NASA/ -type f ! -iname "x" -delete

しかし、これはあまり簡単ではないため、bash スクリプトを使用する必要があります。

もっと簡単な方法を見逃していますか? これを 1 つのコマンドで実行するにはどうすればよいですか?

答え1

GLOBIGNOREを使用して、グロブ中に無視される名前を設定し、 を使用して*他のすべてのファイル/ディレクトリと一致させることができます。

GLOBIGNORE='a:b:x'; rm -r *

例:

$ tree 
.
├── a
│   ├── 1
│   ├── 2
│   └── 3
├── b
│   ├── 1
│   ├── 2
│   └── 3
├── c
│   ├── 1
│   ├── 2
│   └── 3
├── x
├── y
└── z

/NASA$ GLOBIGNORE='a:b:x'

/NASA$ rm -r *

/NASA$ tree 
.
├── a
│   ├── 1
│   ├── 2
│   └── 3
├── b
│   ├── 1
│   ├── 2
│   └── 3
└── x

あるいは、次のディレクトリfindから を使用することもできますNASA

find . -maxdepth 1 ! -name '.' ! -regex '.*/\(a\|b\|x\)$' -exec rm -r {} +

例:

/NASA$ tree 
.
├── a
│   ├── 1
│   ├── 2
│   └── 3
├── b
│   ├── 1
│   ├── 2
│   └── 3
├── c
│   ├── 1
│   ├── 2
│   └── 3
├── x
├── y
└── z


/NASA$ find . -maxdepth 1 ! -name '.' ! -regex '.*/\(a\|b\|x\)$' -exec rm -r {} +


/NASA$ tree 
.
├── a
│   ├── 1
│   ├── 2
│   └── 3
├── b
│   ├── 1
│   ├── 2
│   └── 3
└── x

答え2

拡張グロビングを使うこともできますが、感嘆符は前にパターン:

rm -rf NASA/!(a|b|x)

オンになっていない場合はextglob、まずオンにします。

shopt -s extglob

関連情報