1つとその子孫以外のすべてのディレクトリを親ディレクトリ内から削除する


8

ディレクトリ構造

ディレクトリBとDを削除したいのですが、Cとそのすべての子孫のファイルとディレクトリを保持したいのです。1つのディレクトリとその子を除く、親ディレクトリのすべての子ディレクトリを削除するコマンドは何ですか。

感謝します。


削除したいディレクトリは空ですか?
オタク長老2016


親ディレクトリ(A例では)に直接配置されているファイルはどうですか?それらも削除するか、保持しますか?
バイトコマンダー

バイトコマンダーが求めているのは、Aにファイルがあるのですか?またはディレクトリのみですか?Aの通常のファイルを削除しますか、それともディレクトリのみですか。
Sergiy Kolodyazhnyy 16

回答:


6

あなたが望むのはこのコマンドです:

find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;

デモ:

# List what's inside directory we want to remove
$ ls
file1  file2  keepMe/  removeA/  removeB/
# Testing what find gives without removing
$ find ~/TESTDIR -mindepth 1 -type d -not \( -name "keepMe" \)               
/home/xieerqi/TESTDIR/removeA
/home/xieerqi/TESTDIR/removeB
# Actual removal and testls
$ find ~/TESTDIR -mindepth 1 -maxdepth 1 -type d -not \( -name "keepMe" \) -exec rm -rf {} \;
$ ls
file1  file2  keepMe/

説明:

  • find DIRECTORY DIRECTORYを操作するためのfindコマンドを呼び出す
  • -mindepth 1 :ディレクトリのコンテンツでのみ機能し、レベル0のディレクトリ自体は避けます
  • -maxdepth 1:サブディレクトリに降りることを防ぎます(rm -rfとにかく再帰的であるため、サブディレクトリに降りてそれらを削除する必要はありません)
  • -type d :ディレクトリのみを検索
  • -not \( -name "keepMe" \) 保持したい名前のアイテムを無視する
  • -exec rm -rf {} \; 見つかったアイテムごとに削除を実行する

素晴らしい説明。私にとってはキーストロークが多すぎます...
オタク長老

1
find良い友人はここですが、バッシュのfortestより良い友達です...>: - D
バイト司令

8

bashシェルの拡張glob機能(現在のUbuntuインストールではデフォルトで有効になっています)を使用すると、

$ tree A
A
├── B
├── C
│   ├── ac1
│   └── ac2
└── D

5 directories, 0 files

を除くすべてのものCとその内容をグロブ式を使用してアドレスすることができますA/!(C)すなわち

$ echo A/!(C)
A/B A/D

したがって、ディレクトリとその内容以外のすべてを削除Cするには、単純に使用できます

rm -rf A/!(C)

去る

$ tree A
A
└── C
    ├── ac1
    └── ac2

3 directories, 0 files

この機能について知っていることは驚くべきことです。それは私のsshの後に素晴らしい作品と、手動で実行するが、私は`「-bash取得:行1:予期しないトークンの近くに構文エラー('"私は経由してリモートで実行したときにssh $VM_ADDRESS "rm -rf $APP_FOLDER/!(node_modules)"任意のアイデアどうもありがとうございました。?。
レナート・ガマ

@renatoargh extglobシェルオプションはインタラクティブシェルでのみ有効です-強制的sshに実行できるかどうか不明です
steeldriver

5

1つの簡単な方法は、trash-cliを使用することです。

あなたはそれをインストールすることができます sudo apt-get install trash-cli

インストールしたらcd /A、次のコマンドtrash B Dで親ディレクトリAに移動し、コマンドを発行し ます。BとDは削除するディレクトリです(これらは最終的には、それらが存在するドライブのゴミ箱に移動するため、間違いを犯した場合は、ファイルを回復する)

Ubuntu 16.04および14.04でテスト済み


これは次のようなもので簡略化できtrash ! Cますか?
Sergiy Kolodyazhnyy 16

@Serg Nope trash: cannot trash non existent ! '`
オタク長老

@SergとCがゴミ箱に落ちる...
オタク長老

それを見つけた:stackoverflow.com/q/216995/3701431extglobただし、 有効にする必要があります。
Sergiy Kolodyazhnyy 16

@Serg手元にある仕事にもよりますが、それは非常に役立つかもしれません!;-)
オタク長老

4

次のように、Bashのforループを使用してtest、目的のディレクトリをフィルタリングし、ディレクトリrm -rfを再帰的に削除するコマンドを使用します。

for x in /path/to/parent/*; do test "$x" != "dir_survive" && rm -rf "$x"; done

これは内部のすべての要素(ファイルとディレクトリ)を反復処理し/path/to/parent/、名前がと等しくない場合は再帰的に要素を削除しdir_surviveます。親ディレクトリが現在のディレクトリの場合、*パスとしてのみ書き込むことができます。

不明な点があり、何のアクションも実行せずに最初に削除される要素をテストしたい場合rm -rfは、上記のコマンドのを単にに置き換えるechoだけで、削除候補のみが出力されます。

実行例は次のとおりです。

$ tree
.
├── dir1
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
├── dir2
│   ├── subdir1
│   │   ├── file1
│   │   └── file2
│   └── subdir2
│       ├── file1
│       └── file2
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

9 directories, 12 files

$ for x in *; do test "$x" != "dir_survive" && rm -rf "$x"; done

$ tree
.
└── dir_survive
    ├── subdir1
    │   ├── file1
    │   └── file2
    └── subdir2
        ├── file1
        └── file2

3 directories, 4 files
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.