Jak mogę usunąć wszystkie pliki z katalogu, gdy zgłasza „Za długa lista argumentów”

11

Mam katalog zawierający kilkaset tysięcy plików.

Chcę usunąć wszystkie pliki, ale rm * -f zgłasza: „lista argumentów za długa”

Jaki jest najlepszy sposób na wyczyszczenie tego katalogu?

Brent
źródło
Powiązane, częściowo zduplikowane: unix.stackexchange.com/questions/37329/…
Denilson Sá Maia

Odpowiedzi:

11

Jeśli nie możesz usunąć katalogu, zawsze możesz użyć find.

find . -maxdepth 1 -type f -exec rm -f {} \;

Spowoduje to usunięcie wszystkich plików z bieżącego katalogu i tylko bieżącego katalogu (nie podkatalogów).

chudy
źródło
prawie idealne (patrz też mój post)
asdmin
2
W systemie Linux możesz to zrobić jeszcze szybciej, używając „+” zamiast „\;”. Spowoduje to, że usunie więcej plików na „rm” za jednym razem.
Thomas
5
Jeszcze szybciej: find dir/to/delete -delete(Nie odradza rmprocesu na plik do usunięcia).
Morten Siebuhr
Morten: Nigdy nie wspominał o chęci usunięcia samego katalogu, eh powiedział, że tylko te pliki. find dir/to/delete -type f -delete
richo,
21
odnaleźć . -maxdepth 1 -type f -exec rm -f {} \;

zajmuje to po prostu zbyt długo (jedno wykonanie rm na plik).

ten jest o wiele bardziej wydajny:

odnaleźć . -maxdepth 1 -typ f -print0 | xargs -r0 rm -f

ponieważ do rm potrzeba tyle nazw plików, ile argumentów, to uruchamia rm przy następnym załadowaniu nazw plików ... może się zdarzyć, że rm jest wywoływany tylko 2 lub 3 razy.

asdmin
źródło
5
Cieszę się, że ktoś wie, jak działa find ... Zastanów się również nad nowym poleceniem gnu find -delete action lub -exec command {} +, które działa jak xargs. Zobacz dział „znajdź człowieka”.
Kyle Brandt
Nie wiedziałem o -exec cmd {} +. To wygląda raczej użytecznie. Nieco bardziej ogólny niż -delete :)
David Pashley
-delete może być w porządku, ale ja osobiście wolę polecenia, które mogą być używane na różnych komputerach. Systemy Solaris, z którymi pracuję, są starsze, więc -delete nie będzie na nich
działało
2
Dodawanie ionicetuż przed tym rmjest dobrym pomysłem, jeśli komputer jest używany przez inne osoby w tym samym czasie.
Hubert Kario
6

Oba te rozwiązania obejdą problem. Jest to analiza odpowiedniej wydajności każdej techniki nad tutaj .

find . -name WHATEVER -exec rm -rf {} \;

lub

ls WHATEVER | xargs rm -rf

Problem wynika z bash rozwijania „*” z każdym pojedynczym elementem w katalogu. Oba rozwiązania działają kolejno dla każdego pliku.

Coops
źródło
2
Rozwiązanie wyszukiwania jest wolniejsze w przypadku wielu plików, ponieważ wywołuje polecenie rm dla każdego pliku. Rozwiązanie xargs jest szybsze, ale działa tylko wtedy, gdy nazwy plików nie zawierają spacji (w przeciwnym razie potrzebujesz GNU find i find . -print0 | xargs -0 rm).
robcast
"find. -name WHATEVER -print0 | xargs -0 rm -rf" będzie bardziej wydajne. find rozwiąże rm dla każdego pliku, gdzie xargs zredukuje go do minimum. Potrzebujesz -print0 i -0, aby poradzić sobie z plikami ze spacjami w. Prawdopodobnie chcesz także użyć -depth przy szukaniu, więc najpierw wykonuje głębokie wyszukiwanie.
David Pashley,
Polecenie ls nie będzie działać, ponieważ to również zwraca „listę argumentów za długą”
Brent,
2
Robisz „ ls *”, a „ *” rozwija się do listy argumentów, na które powłoka narzeka, że ​​jest za długa. ls .Zamiast tego rób „ ” (lub przejdź na wyższy poziom katalogu i rób „ ls [dirname]”).
James Sneeringer
drugi wiersz komend (ls WHATEVER | xargs rm -rf) nie działałby z tego samego powodu, dla którego pytanie nie działało: WHATEVER zostałby zastąpiony przez powłokę o
nadmiernej
3

Udało mi się to zrobić, wykonując kopię zapasową jednego poziomu:

cd ..

I działa:

rm directory name -rf

A następnie ponowne utworzenie katalogu.

Brent
źródło
1
działa tylko wtedy, gdy nie musisz mieć katalogu na stałe, a wszystkie pliki i katalogi zostaną rekurencyjnie usunięte. większość przypadków w moim życiu nie zadziałałoby w ten sposób.
asdmin
2

Wszystkie te wywołania znalezienia są bardzo miłe, ale rzadko pamiętam dokładnie nomenklaturę potrzebną, gdy mi się spieszy: zamiast tego używam ls. Jak ktoś wspomina, ls. działałoby, ale wolę ls -1 jak w:

ls -1 | xargs -n 100 rm -rf

Figura -n xxx jest dość bezpieczna do zabawy, ponieważ przekroczenie maksimum albo zostanie automatycznie skorygowane (jeśli zostanie przekroczony rozmiar max; patrz -s) lub jeśli zostanie przekroczona args-max dla aplikacji, zwykle będzie to raczej oczywisty.

Należy zauważyć, że grep jest przydatny do wstawiania w środku tego łańcucha, gdy chcesz tylko usunąć podzbiór plików w dużym katalogu, a nie z jakiegokolwiek powodu chcesz użyć find.

Ta odpowiedź zakłada, że ​​korzystasz z podstawowych narzędzi Gnu dla swojego ls, xargs itp.

rixtertech
źródło
Czy to zadziała z katalogiem, który jest zbyt duży, aby „ls” działał? (ten sam błąd - zbyt długa lista argumentów)
Brent
Tak Brent: pamiętaj, aby nie używać specyfikacji plików podczas wywoływania ls. Użyj tylko -1 (kreska pierwsza), jak pokazano powyżej. I jak wyjaśniono powyżej, użyj grep po ls, jeśli chcesz sparować listę plików. Jeśli pojawia się błąd „zbyt długi” po upewnieniu się, że nie używasz symboli wieloznacznych z ls, być może xargs narzeka. Użyj „xargs -n 5” zamiast „xargs -n 100” i zdecydowanie powinieneś być bezpieczny, jeśli trochę wolniej.
rixtertech,
1

Możesz użyć tej -exec +opcji, aby dowiedzieć się, który spróbuje uruchomić rm tak często, jak to możliwe, co może być szybsze.

find . -type f -exec rm '{}' +
Rory
źródło
0

Oto wersja do usuwania dużej liczby plików, gdy system musi pozostać responsywny.

Działa poprzez wydawanie pracy w małych partiach (domyślnie 100 plików) i czekanie trochę na zakończenie innych zadań.

Doskonale działał, usuwając ponad pół miliona plików z jednego katalogu na ext3. Wyświetla procent zrobiony jako mały bonus

noOfFiles=`ls -U | wc -l`
n=0
while (ls -U | tail -n 100 | xargs rm -f); do 
   n=$((n+100));
   sync;
   echo -en "$((n*100/noOfFiles))%, ($n of $noOfFiles)\r";
   sleep 5;
done
Hubert Kario
źródło
0

Rozwiązuje błędy „argument zbyt długi” lub „nie można przydzielić pamięci”

To załatwiło ponad 220 000 plików w folderze sesji ...

Zaleta: natychmiast rozpoczyna usuwanie plików

ścieżka cd / do / folderu
ls -f | xargs rm -f -v

KLIKNIJ, aby wyświetlić zrzut ekranu usuwanych plików - (wszystkie pliki zostały usunięte w ~ 15 minut)

-f (po ls) powstrzymuje się od presortowania

-v (po rm) wyświetla każdy plik jako usunięty

-f (po rm) wymusza przejście bez pytania o pliki chronione przed zapisem

Wskazówka: najpierw zmień nazwę folderu (poprzednia sesja na session_old), aby zapobiec dodawaniu dodatkowych plików wygenerowanych automatycznie podczas próby ich usunięcia. Możesz ręcznie przerobić oryginalny katalog, jeśli nie zrobi to automatycznie, jak w moim przypadku

kilcode
źródło
Co nowego w twojej odpowiedzi brakowało w poprzednich?
user2233709