1つを除いて親のすべてのファイルを削除する

1つを除いて親のすべてのファイルを削除する

パス内にあり、その中のすべてのエントリを/parent/child1/child2削除したい場合( . を除く)、このコマンドがどのように実行されるかを教えてくれる人はいますか?parentchild2child1parent

答え1

bashシェルを使用しているとします。

shopt -s dotglob extglob
rm -rf ../../!(child1)

ここのコマンドは、shoptシェルで2つのシェルオプションを有効にしますbash。まず、dotglob隠された名前がファイル名のワイルドカードパターンと一致することを確認してください。 2番目のものは、extglobいくつかの拡張されたグローブパターン(元のkshシェルで)を有効にします。

parent2行目は拡張ワイルドカードパターンを使用して、ディレクトリの名前を除くすべてのエントリを一致させますchild1。このディレクトリの内容はparent私たちより2つ上のレベルにあるので、最初に使用してから名前を除くすべてと一致するパターンを追加します../../!(child1)child1

rm -rf一致するすべての名前を(再帰的)削除に渡します。

../../!(child1)パターンで相対パスを使用する代わりに、ディレクトリへの絶対パスを使用することもできますparent。あなたの質問によると、絶対パスはそのため/parentパターンはなります/parent/!(child1)parentディレクトリに基づく実際の場所がわからない場合は、絶対パスを使用する方が安全です。


この問題を解決するもう一つの明確な方法は、まずchild1ディレクトリを別の場所に移動し、ディレクトリをparent削除して再作成し、ディレクトリをchild1元に戻すことです。

ここでは絶対パス名を使用しています(相対パス名を使用すると、現在のディレクトリを基準に移動するため混乱する可能性がありますparent)。

mv /parent/child1 /tmp
rm -rf /parent
mkdir /parent
mv /tmp/child1 /parent

答え2

GNU findがある場合は、このコマンドを使用できます。

find ../.. -depth -not -path "../../child1/*" -not -samefile ../.. -not -samefile ../../child1 -exec rm -r {} \;

あなたが実際にその中にいることを確認してください/parent/child1/child2

関連情報