web-dev-qa-db-ja.com

ワイルドカードを使用してディレクトリを再帰的に削除するにはどうすればよいですか?

WD My Book World EditionでSSHを使用しています。基本的に、特定のディレクトリレベルから開始し、.Apple*に一致するすべてのサブディレクトリを再帰的に削除します。どうすればいいですか?

私は試した

rm -rf .Apple*およびrm -fR .Apple*

サブディレクトリ内でその名前に一致するディレクトリも削除されませんでした。

55
codedog

findは、ツリー全体に対して選択的にアクションを実行するのに非常に役立ちます。

find . -type f -name ".Apple*" -delete

ここで、-type fは、それがディレクトリではなくファイルであることを確認します。また、シンボリックリンク、ソケット、およびその他のものもスキップするため、目的のものとは異なる場合があります。 ! -type dを使用できます。これは、文字通りディレクトリではないことを意味しますが、文字デバイスとブロックデバイスを削除することもできます。 findのmanページにある-type述語を見ることをお勧めします。

ワイルドカードを使用して厳密に行うには、高度なシェルサポートが必要です。 Bash v4には globstarオプション があり、**を使用してサブディレクトリを再帰的に照合できます。 zshkshもこのパターンをサポートしています。それを使用すると、rm -rf **/.Apple*を実行できます。これはPOSIX標準ではなく、移植性も低いため、スクリプトでの使用は避けますが、1回限りの対話型シェルアクションの場合は問題ありません。

76
Shawn J. Goff

findの意図的な動作のためにfind-deleteと一緒に使用する問題に遭遇しました(つまり、パスが./で始まる場合、削除を拒否します)。そのmanページで述べた:

 -delete

見つかったファイルやディレクトリを削除します。常にtrueを返します。これは、findがツリーを再帰するときに、現在の作業ディレクトリから実行されます。 「。」に関連するパス名に「/」文字が含まれているファイル名は削除されません。セキュリティ上の理由から。
このオプションでは、深さ優先のトラバーサル処理が暗黙指定されます。
以下のシンボリックリンクはこのオプションと互換性がありません。

代わりに、私はただ行うことができました

find . -type d -name 'received_*_output' -exec rm -r {} +

あなたの場合、グロブ(アスタリスク、*)を引用することが解決策のようですが、他の誰かが同様の問題を抱えている場合に備えて私の答えを提供したいと思いました。

注:以前は、私の答えは次のようにすることでしたが、@ Wildcardはそれを行う際のセキュリティ上の欠陥をコメントで指摘しました。

find . -type d -name 'received_*_output' | xargs rm -r
17
Pat

可能性のあることは、rm/findコマンドに問題はないが、ログインしているユーザーには実際には削除権限がないということです。使用する ls -lを使用して、権限のあるものを一覧表示し、idおよびgroupsコマンド(どちらも使用可能である必要があります)を使用して、自分が誰であるかを識別できます。これを行う「間違ったユーザー」である場合は、ファイルの権限/所有権を変更するか、別のユーザーに切り替える必要があります。

0
froztbyte

試してください:

shopt -s dotglob           # using Bash
printf '%s\n' ./.Apple*    # test
#rm -rf ./.Apple*    
0
jan