以外の現在のディレクトリツリー内のすべてのファイルを削除したいと思いますsave
。次のコマンドを実行しました。
find . \( -name save -prune \) -o -type f -ls | grep /save/
何も見つかりませんでした。しかし、このコマンドを実行すると:
find . \( -name save -prune \) -o -type f -delete
/save/のすべてのファイルが消えました。私は何を見逃していますか?
答え1
-delete
-depth
適用できないことを意味します-prune
(-depth
葉で始まる)。 GNUバージョンのマニュアルにこれに関する警告があります(これはGNUや他の実装でもサポートされているFreeBSD拡張です-delete
)。find
info -- find -delete
コマンドラインで「-Delete」操作を使用すると、「-Deep」オプションが自動的にオンになります(*検索式注::)。以前にテスト用に「-print」を使用したことがある場合は、これは驚くことがあるため、通常「-深さ」を明示的に使用することを覚えておくのが最善です。
info -- find -prune
「-delete」は「-deep」を意味するため、「-prune」を「-delete」と組み合わせて使用すると、予想以上に多くのファイルが削除される可能性が高くなります。
ここでは、以下を使用することを選択できますrm
。
find . -name save -prune -o -type f -exec rm -f {} +
(可能安全ではない他の人が書き込むことができるディレクトリがある場合、コマンドを実行するときにディレクトリをシンボリックリンクに置き換えると、現在のディレクトリツリーの外側のファイルを削除できるためです。
より安全な選択肢:
find . -name save -prune -o -type f -execdir rm -f -- {} \;
上記の問題はありませんが、rm
ファイルごとに1つずつ実行することを意味します。これは--
GNU実装ではなくFreeBSD実装で必要です./
。
またはCostasが提案したように:
LC_ALL=C find . ! -name save ! -path '*/save/*' -type f -delete
(しかし、これはまだ不必要にディレクトリを削除しますsave
)
したがって、すべてのバイトシーケンスLC_ALL=C
と*
一致します(現在のロケールで有効な文字を形成しないバイトも含む)。これはエラーメッセージの言語(ユーザー言語ではなく英語)に影響します。