パス内にあり、その中のすべてのエントリを/parent/child1/child2
削除したい場合( . を除く)、このコマンドがどのように実行されるかを教えてくれる人はいますか?parent
child2
child1
parent
答え1
bash
シェルを使用しているとします。
shopt -s dotglob extglob
rm -rf ../../!(child1)
ここのコマンドは、shopt
シェルで2つのシェルオプションを有効にしますbash
。まず、dotglob
隠された名前がファイル名のワイルドカードパターンと一致することを確認してください。 2番目のものは、extglob
いくつかの拡張されたグローブパターン(元のksh
シェルで)を有効にします。
parent
2行目は拡張ワイルドカードパターンを使用して、ディレクトリの名前を除くすべてのエントリを一致させます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