-delete
oznacza, -depth
że nie działa -prune
( -depth
zaczyna się od liści). Jest o tym ostrzeżenie w podręczniku wersji GNU ( -delete
jest to rozszerzenie FreeBSD obsługiwane teraz także przez GNU find
i kilka innych implementacji).
info find --index-search=-delete
Użycie akcji „-delete” w wierszu poleceń automatycznie włącza opcję „-depth” (* notatka znajdź Wyrażenia: :). Może to być zaskakujące, jeśli wcześniej testowałeś tylko z „-print”, więc zazwyczaj najlepiej jest pamiętać, aby używać „-depth” wyraźnie.
info find --index-search=-prune
Ponieważ „-delete” oznacza „-depth”, użycie „-prune” w połączeniu z „-delete” może skutkować usunięciem większej liczby plików niż zamierzałeś.
Tutaj masz opcję użycia rm
zamiast tego:
find . -name save -prune -o -type f -exec rm -f {} +
(potencjalnie niebezpieczne, jeśli istnieją katalogi do zapisu przez innych, ponieważ można spowodować usunięcie plików poza bieżącym drzewem katalogów poprzez zastąpienie katalogów dowiązaniami symbolicznymi podczas uruchamiania tej komendy).
Bezpieczniejsza alternatywa:
find . -name save -prune -o -type f -execdir rm -f -- {} \;
To nie ma wyżej wspomnianego problemu, ale oznacza uruchomienie jednego rm
na plik. Jest --
to konieczne do implementacji FreeBSD, a nie GNU, który poprzedza nazwy plików ./
.
Alternatywnie, jak sugeruje Costas:
LC_ALL=C find . ! -name save ! -path '*/save/*' -type f -delete
(ale to wciąż niepotrzebnie schodzi do save
katalogów)
LC_ALL=C
Jest tak *
dopasowuje dowolną sekwencję bajtów (nawet tych, które nie tworzą poprawnych znaków w bieżącej lokalizacji). Pamiętaj, że wpłynie to na język komunikatów o błędach (angielski zamiast języka użytkownika).
mv save/ ../some/safer/location
przed takim „ogólnym” poleceniem usuwania (... ale oczywiście przed twoim postem zrobiłbym to samo sprawdzenie i napotkałem ten sam problem!). Teraz znajdź dobre „cofnięcie usunięcia” dla systemu plików, w którym pliki były na ^^