Jak rekurencyjnie usuwać katalogi ze znakiem wieloznacznym?


51

Pracuję za pośrednictwem SSH na WD My Book World Edition. Zasadniczo chciałbym zacząć od określonego poziomu katalogu i rekurencyjnie usunąć wszystkie pasujące podkatalogi .Apple*. Jak miałbym to zrobić?

próbowałem

rm -rf .Apple* i rm -fR .Apple*

nie usunięto katalogów pasujących do tej nazwy w podkatalogach.

Odpowiedzi:


73

find jest bardzo przydatny do selektywnego wykonywania akcji na całym drzewie.

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

Tutaj -type fupewnia się, że jest to plik, a nie katalog, i może nie być dokładnie tym, czego chcesz, ponieważ pominie również dowiązania symboliczne, gniazda i inne rzeczy. Możesz użyć ! -type d, co dosłownie oznacza nie katalogi, ale możesz także usunąć znaki i zablokować urządzenia. Proponuję zajrzeć do -typeorzeczenia na stronie podręcznika dla find.

Aby to zrobić ściśle przy użyciu symboli wieloznacznych, potrzebujesz zaawansowanej obsługi powłoki. Bash v4 ma globstaropcję , która pozwala rekurencyjnie dopasowywać podkatalogi za pomocą **. zsha kshtakże wspierać ten wzór. Korzystając z tego, możesz to zrobić rm -rf **/.Apple*. To nie jest standard POSIX i nie jest zbyt przenośny, więc unikałbym używania go w skrypcie, ale w przypadku jednorazowej interaktywnej akcji powłoki jest w porządku.


3
Mogę zabrać się find . -type d -name .Apple*do pracy - zawiera listę wszystkich folderów. Jednak nie powiedzie się, gdy dodam -deletena końcu. Po prostu wraca z podsumowaniem użytkowania. Działa na BusyBox v1.1.1. Czy to robi różnicę?
codedog

1
-deletenie jest również POSIX. **został wprowadzony zshna początku lat 90. Jest teraz (według kolejności chronologicznej wyglądu) również w ksh93, fish, bash i tcsh.
Stéphane Chazelas,

1
+1 zarm -rf **/.Apple*
Andrij Bojko

1
@codedog, jeśli -deletenie działa, użyj -exec rm -f {} +zamiast tego.
Wildcard

1
Czy potrafisz findbyć gadatliwy podczas usuwania? Podejrzewam, że metoda „globstar” zrobiłaby to przez dodanie -vprzełącznika.
Demis

16

Wystąpiły problemy podczas używania findz -deletepowodu celowego zachowania find(tj. Odmowy usunięcia, jeśli ścieżka zaczyna się od ./, co robią w moim przypadku), jak podano na stronie podręcznika:

 -delete

Usuń znalezione pliki i / lub katalogi. Zawsze zwraca true. Wykonuje się to z bieżącego katalogu roboczego, ponieważ find powtarza się w drzewie. Nie będzie próbował usunąć nazwy pliku ze znakiem „/” w nazwie ścieżki względem „.” ze względów bezpieczeństwa.
Ta opcja implikuje przetwarzanie w pierwszej kolejności.
Poniższe dowiązania symboliczne są niezgodne z tą opcją.

Zamiast tego mogłem to zrobić

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

W twoim przypadku wydaje się, że rozwiązanie globu (gwiazdka *) było rozwiązaniem, ale chciałem udzielić odpowiedzi na wypadek, gdyby ktoś miał podobny problem.

UWAGA: Wcześniej moją odpowiedzią było wykonanie następujących czynności, ale @Wildcard zwrócił uwagę na luki w zabezpieczeniach podczas robienia tego w komentarzach.

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

1
Nie ma dobrego powodu, aby użyć xargstutaj. -exec rm -r {} \;lub, lepiej, -exec rm -r {} +zrobi to samo, nie zawodząc nazw plików znaków specjalnych. Zobacz, dlaczego zapętlanie wyników wyszukiwania jest złą praktyką?
Wildcard

Dobrze wiedzieć. IMO nie jest warte pochwały, ponieważ polecenie wciąż wykonuje zadanie, ale optymalizacja wydajności jest doceniana.
Pat

1
Gdyby to była tylko optymalizacja wydajności, zgodziłbym się z tobą, ale tak nie jest. To dziura bezpieczeństwa. Nie obsługujesz poprawnie plików z białymi znakami, a złośliwie spreparowana nazwa pliku spowoduje utratę danych. Zobacz także Implikacje bezpieczeństwa dla zapomnienia o cytowaniu zmiennej w powłokach bash / POSIX ; niektóre z nich mają zastosowanie i mogą przynajmniej dać ci pojęcie o rodzaju problemów, o których mówię.
Wildcard

Spróbuj mkdir -p $'blah\nDocuments\n/etc\n/home\n/received__output'w swoim katalogu, a następnie ponownie uruchom to samo polecenie, jeśli nie uważasz, że istnieje ryzyko utraty danych. Albo, ponieważ pytanie o Mac OS mkdir -p $'blah\nDocuments\n/Users\n/Applications\n/received__output'. ( Ostrzeżenie: jeśli to zrobisz, usuniesz wszystkie swoje pliki.). To mój punkt.)
Wildcard

0

Możliwe jest to, że nie ma nic złego w poleceniu rm / find, ale użytkownik, z którym jesteś zalogowany, tak naprawdę nie ma uprawnień do usuwania. Użyj ls -ldo listy rzeczy z ich uprawnieniami, można zidentyfikować, kim jesteś z idi groupskomend (albo powinna być dostępna). Jeśli jesteś „niewłaściwym użytkownikiem”, musisz albo zmienić uprawnienia / własność plików, albo przełączyć się na innego użytkownika.


0

Próbować:

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

1
dotglobjest tu bezużyteczne. Zobacz tę stronę, aby zobaczyć przykład działania dotglob.
amfetamachina

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.