Rekurencyjnie usuwaj pliki

140

Czy ktoś ma rozwiązanie, aby usunąć te brzydkie pliki ._ i .DS_Store, które dostaje się po przeniesieniu plików z komputera Mac na serwer z systemem Linux?

określić katalog startowy i pozwolić mu odejść? jak / var / www / html / down ...

JT.
źródło
Chociaż nie jest to duplikat IMO, powinieneś
rzucić
Chociaż nie to, o co prosisz. Twierdzę, że to lepsze rozwiązanie: unix.stackexchange.com/questions/9665/ ...
Viktor

Odpowiedzi:

169

przejdź do katalogu i użyj:

find . -name ".DS_Store" -print0 | xargs -0 rm -rf
find . -name "._*" -print0 | xargs -0 rm -rf

Nie testowane, wypróbuj je najpierw bez xargs!

Możesz zamienić kropkę po znalezieniu na katalog zamiast najpierw przechodzić do katalogu.

find /dir/here ...
X-Istence
źródło
2
Wiem, że jego pytanie o to nie pytało, ale nigdy nie pamiętam: czy twój przykład obsługuje nazwy plików ze spacjami?
Grundlefleck
4
Tak, do tego służą print0 i -0 do xargs. Normalnie nie obsługuje poprawnie spacji, jednak z print0 wypisze nazwę pliku ze znakiem null na końcu linii, którego xarg z -0 użyje następnie do przekazania pełnej ścieżki do xargs bez szans na uzyskanie białych znaków użycie drugiego lub trzeciego parametru w poleceniu rm, co może być naprawdę złe!
X-Istence
7
@X: nowszy findutils obsługuje -deleteakcję, która może to skrócić. @JT: To wyszukuje rekurencyjnie pod .. Zależy od tego, ile jest plików i podkatalogów ... czy nie możesz po prostu zabronić ich przesyłania?
ephemient
1
Korzystanie z -rflagą (rekurencyjnych) nie jest zalecane, ponieważ w tym przypadku nie chcesz, aby usunąć wszelkie katalogi ..
Daniel Zohar
2
@IlmariKaronen: słuszna uwaga. Czy nie command rmbyłoby lepszym (czyli bardziej bezpośrednim) rozwiązaniem? (Mówiąc „bezpośrednio”, mam na myśli, że dotyczy konkretnie danego problemu i niczego innego, a zatem jest mniej prawdopodobne, że będzie miał jakiekolwiek niepożądane skutki uboczne, a także będzie bardziej oczywiste dla każdego, kto musi utrzymywać kod później.)
ikonoklast
93
find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete
OneOfOne
źródło
86

Nowsze findutils obsługuje -delete, więc:

find . -name ".DS_Store" -delete

Dodaj, -printaby również uzyskać listę usunięć.

Wydaje mi się, że polecenie zadziała, jeśli masz aktualny system POSIX. Przynajmniej działa dla mnie na OS X 10.8 i działa dla innych, którzy przetestowali go na macOS 10.12 (Mojave).

Podziękowania dla @ephemient w komentarzu do posta @ X-Istence (uznał, że był on wystarczająco pomocny, aby uzasadnić własną odpowiedź).

grzechotka
źródło
1
Działa również w OSX 10.6.
hoss
3
Najczystsze i najprostsze rozwiązanie, +1!
limist
6
@OneOfOne: jak mówi mój komentarz, otrzymałem to od @ ephemient. Jako początkujący bash, znalazłem twoje (być może bardziej poprawne) rozwiązanie o wiele mniej czytelne i użyteczne. Mogą być funkcjonalnie identyczne, ale uważam, że ta składnia zapewnia większą przejrzystość.
rattray
1
„.” nie jest konieczne, ponieważ finddomyślnie powraca do bieżącego katalogu roboczego.
Tom Russell,
W nowszych wersjach programu katalog można pominąć, co będzie oznaczało bieżący katalog roboczy ( wikipedia ). Nadal potrzebujesz .systemu macOS 10.12 (Sierra).
Dem Pilafian
18

Proste polecenie:

rm `find ./ -name '.DS_Store'` -rf
rm `find ./ -name '._'` -rf

Powodzenia!

KimKha
źródło
1
To działa świetnie. ALE słowo ostrzeżenia, właśnie użyłem tego rm -i znaleziska ./ -name '* py'` -rf , which did NOT prompt me to delete files. you will need to take it on the end (i.e. -rfi`). Dzięki Bogu za mój skrypt zapasowy.
ryanjdillon
1
Jeśli jest zbyt wiele plików, kończy się to z błędem:-bash: /bin/rm: Argument list too long
Viktor
12
cd /var/www/html && find . -name '.DS_Store' -print0 | xargs -0 rm
cd /var/www/html && find . -name '._*' -print0 | xargs -0 rm
mopoke
źródło
2
Podobało mi się to bardziej po prostu dlatego, że "rm" nie ma "-r", które nie jest konieczne do tego konkretnego zadania.
lotsoffreetime
6

Możesz przełączyć się na zsh zamiast bash. Dzięki temu możesz używać ** do dopasowywania plików w dowolnym miejscu w drzewie katalogów:

$ rm /var/www/html/**/_* /var/www/html/**/.DS_Store

Możesz je również łączyć w ten sposób:

$ rm /var/www/html/**/(_*|.DS_Store)

Zsh ma wiele innych funkcji, których brakuje bashowi, ale tylko ta jest warta przejścia. Jest dostępny w większości (prawdopodobnie wszystkich) dystrybucjach Linuksa, a także w Cygwin i OS X.

Więcej informacji można znaleźć w witrynie zsh .

Dave Kirby
źródło
1
Możliwy problem: ponieważ nie używasz xargs, możesz napotkać ograniczenie długości argumentów wiersza poleceń. Również Bash 4 obsługuje **też :-) (choć nie domyślnie, shopt -s globstarmusi być ustawiony)
ephemient
4
find . -name "FILE-TO-FIND"-exec rm -rf {} \;
Martin Beckett
źródło
Używanie funkcji exec dla każdego znalezionego pliku nie jest szybkie. Szybciej jest je wydrukować, a następnie raz użyć xargs do wywołania rm.
X-Istence
3
Jeśli jednak masz znak, findktóry go obsługuje, +jest podobny do xargs: find . -name "FILE-TO-FIND" -exec rm -rf {} +- (również brakuje ci spacji wcześniej -exec)
Wstrzymano do odwołania.
3
nigdy nie mieliśmy xargów za moich czasów. I musieliśmy iść do szkoły, pod górę w obie strony .......
Martin Beckett
3

Przykład rekurencyjnego usuwania pliku „Thumbs.db”;

find . -iname "Thumbs.db" -print0 | xargs -0 rm -rf

Zatwierdź przez:

find . -iname "Thumbs.db"

Powinno to teraz nie wyświetlać żadnych wpisów z „Thumbs.db” w bieżącej ścieżce.

parasrish
źródło
Upewnij się, że Twoja odpowiedź drukuje listę elementów, które są usuwane, i wyjaśnij, dlaczego ktoś może chcieć użyć, xargsa print0zamiast exec(istnieją powody).
Josh Habdas
3

Lepiej jest zobaczyć, co jest usuwane, dodając -print do tej odpowiedzi

find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete -print
Ahmad Yoosofan
źródło
2

jeśli masz Bash 4.0 ++

#!/bin/bash
shopt -s globstar
for file in /var/www/html/**/.DS_Store /var/www/html/**/._ 
do
 echo rm "$file"
done
ghostdog74
źródło
2
Uruchamianie nowej kopii rm dla każdego pliku jest marnotrawstwem.
X-Istence
2
@ X-Istence przedwczesna optymalizacja jest marnotrawstwem
Lucina
Głosowany za oryginalnością i wykorzystaniem nowszych innowacji bash.
Josh Habdas
1

Kilka uwag:

„-delete” nie jest cykliczne. Więc jeśli .TemporaryItems (folder) zawiera pliki, polecenie kończy się niepowodzeniem.

Istnieje wiele takich nieznośnych plików utworzonych przez komputery Mac: .DS_Store ._. DS_Store .TemporaryItems .apdisk

To jedno polecenie dotyczy wszystkich z nich. Zapisuje ciągłe wyszukiwanie wielu dopasowań.

find /home/foo \( -name '.DS_Store' -or -name '._.DS_Store' -or -name '._*' -or -name '.TemporaryItems' -or -name '.apdisk' \) -exec rm -rf {} \;
Karan Bhalla
źródło
0

Działa to również:

sudo rm -rf 2018-03-*

tutaj twoje usuwanie plików z nazwami formatu 2018-03- (coś innego)

nie komplikuj

pranavhd
źródło
Nie wyjaśniasz, kiedy ktoś może chcieć poprzedzić polecenie przedrostkiem, sudoani nie podajesz żadnych informacji, jak rmdziała w kontekście twojej odpowiedzi.
Josh Habdas