空のサブフォルダーを削除し、親フォルダーを保持します


15

使用するとき

find /home/user/parentdir -type d -empty -delete

空のサブフォルダーを再帰的に探して/home/user/parentdir削除します。しかし、/home/user/parentdirも空の場合、parentdirフォルダも削除されますが、これは私にとって望ましくありません。

これparentdirrsyncいくつかのファイルに保存して、バックアップまたはクラウドに保存したい。処理後、空のフォルダーを削除する必要がありますが、parentdir毎回再作成するのは非生産的です。

維持する提案はありparentdirますか?私は.nocopyその中にファイルを作成して、から除外することを考えましたrsyncが、やり過ぎのようです。もっとエレガントな方法はありますか?


/ parentdirの最後にスラッシュ/を追加すると(つまり/ parentdir /)、違いが生じますか?
グラハム

6
-mindepth 1
スチールドライバー

@Graham / parentdir /はparentdirも削除するため、違いはありません。
TNT

ああ、@ Amourkが彼の答えで言及している最後の*を見逃したようです。
グラハム

回答:


25

単純にfind /home/user/parentdir -mindepth 1 -type d -empty -delete

見て:

$ mkdir -p test1/test2
$ find test1 -type d
test1
test1/test2
$ find test1 -mindepth 1  -type d
test1/test2

find /home/user/parentdir/* AmourKの答えでは、そこにあるファイルの多くがあり、それがovercomplicatedされたときには望ましくありません。


15

/*の最後に追加することによりparentdir、自分parentdir自身ではなく、parentdirのすべてのサブディレクトリでアクションを実行しています。そして、同じように/home/user/古いコマンドでparentdirは削除されませんが、以下のコマンドでは削除されません。 *グロブ演算子と呼ばれ、任意の文字列に一致します。

find /home/user/parentdir/* -type d -empty -delete


7
一つのことがある場合は、このアプローチがあるとの認識することが大きな内のファイル数は/home/user/parentdir/、拡大グロブを超える場合がありARG_MAX、その結果、引数リストが長すぎるエラー。*/ディレクトリにのみ一致するようにglobを変更することで、その可能性を減らすことができます。
スチールドライバー

12
また、これはドットで始まる子を見つけないことに注意してください。そしていつかあなたはこれに気づくでしょう。そして、「。*」の検索を行うと、あなたは巨大な怪我の世界に入ります(「。*」は「..」に一致するため)。私が知っている方法を聞いてください。
グレンウィレン

1
@GlennWillenなぜこの話をするように頼む前に、私たちの前で飲み物を飲みながらバーに座っているべきだと思いますか?
モンティハーダー

@MontyHarder幸いなことに、それほど悪くはありませんでした。それは私の最初のUnixシステムで、私の高校が所有するSolarisマシンでした。「rm」ではなく「chown」を実行していたことを神に感謝します。ルートを使用して、ホームディレクトリ内のすべての所有権を修正しようとしました。代わりに、すべてのホームディレクトリ(およびそのすべてのコンテンツ)の所有権を自分に与え、それらをすべて元に戻す必要がありました。
グレンウィレン

私は同僚に新しい従業員にソフトウェアをインストールする方法を訓練してもらいました。に移動して/tmp、サブディレクトリを作成し、そこにgzip圧縮されたtarballを展開し、インストーラーを実行して、クリーンアップします。初心者rm -rf /tmp/foo-installはそれを行う正しい方法であると考え、経験豊富な手がエピソードIIIの最後のダースベーダーでの最高の印象で「Noooooo」と言ったように、初心者は、 /とEnterキーはお互いにありました。バックアップソフトウェアの復元ディスクから起動し、サーバー全体をテープからリロードする必要がありました。
モンティハーダー

0

php-cliがインストールされている場合、

printf %s $(pwd) | php -r 'function f(string $dir){var_dump($dir);$dir.=DIRECTORY_SEPARATOR;foreach(glob("$dir*",GLOB_ONLYDIR) as $d){f($d);}global $original;if(substr($dir,0,-strlen(DIRECTORY_SEPARATOR))!==$original && empty(glob("$dir*"))){rmdir($dir);}}f(($original=stream_get_contents(STDIN)));'

あなたが望んでいるforeach (RecursiveIteratorIterator(RecursiveDirectoryIterator($dir)) as $p) if (empty($skipped)) $skipped = TRUE; elseif ($p->isDir()) @rmdir($p->getPathname());か、それに近いもの。$skipped最初のものをスキップし@rmdir、dirを削除しようとしますが、空でない場合は暗黙的に(つまり@)失敗します。
chx

0

必要なレベルが1つだけの場合(親フォルダーを残し、空の子フォルダーを削除する)、簡単なトリックはを使用することrmdirです。

rmdir parent/*

すべての空のサブフォルダーを削除しますが、ファイルと空でないフォルダーのエラーのみを出力します。

これは再帰的に機能しませんが、フォルダー構造を知っている場合、次のようなことをする最も速い方法かもしれません

rmdir parent/*/*/* # deletes parent/a/b/c when empty
rmdir parent/*/* # deletes parent/a/b when it is now empty
rmdir parent/* # deletes parent/a when it is now empty

利点:覚えやすく、入力が速く、間違ったパラメーターを選択する可能性がほとんどありません。
欠点:柔軟性が低く、おそらく端末に多くのエラーメッセージが表示されます。

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