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 ...


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 ...

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


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ź).


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!


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

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 .


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 {} \;

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.


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


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

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 {} \;

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


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
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.