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.