Jak usunąć wszystkie pliki .pyc z projektu?


677

Zmieniłem nazwy niektórych plików w dość dużym projekcie i chcę usunąć pozostawione przez nich pliki .pyc. Próbowałem skryptu bash:

 rm -r *.pyc

Ale to nie powtarza się w folderach, jak myślałem. Co ja robię źle?


11
Nie działa, ponieważ w UNIX globusy są rozszerzane przez powłokę, a nie przez uruchamiany program. Jeśli masz a.pyc i b.pyc w bieżącym katalogu, a katalogi foo i bar rmbędą wywoływane z argumentami [-r, a.pyc, b.pyc].
efhemient

1
jeśli martwisz się o przekazanie kodu innym osobom, możesz po prostu dodać go do .gitignore, **/*.pyca potem nie będziesz musiał się tym martwić
bubakazouba,

Odpowiedzi:


1166
find . -name "*.pyc" -exec rm -f {} \;

385
Find ma wbudowaną akcję „-delete”, więc możesz to zrobićfind . -name \*.pyc -delete
Christoffer

51
Co najważniejsze, jeśli jest to maszyna deweloperska, możesz ustawić PYTHONDONTWRITEBYTECODE = True i nigdy nie będziesz musiał tego robić ponownie. Zobacz: ta odpowiedź .
mlissner

5
Nie cytujesz {}. Co by się stało, gdyby przypadkowo podzielił słowo i usunął ścieżkę pośrednią, która nazywa się jak fragment znalezionej ścieżki?
Robottinosino,

20
-deletenie jest częścią specyfikacji POSIX i nie ma gwarancji istnienia we wszystkich implementacjach find.
chepner

7
Jeśli się boisz - co może być dobre - wykonaj pierwsze przejście z -exec echo {} lub - jeśli jesteś bardzo przestraszony - użyj rm -i {}, które pytają za każdym razem lub rm - v {}, aby zobaczyć, co usuwasz.
jeanM

1021

find . -name '*.pyc' -delete

Z pewnością najprostszy.


21
Jeśli Twoja wersja findobsługuje -delete; nie jest częścią standardu POSIX.
chepner

4
To ignoruje pliki i __pycache__katalogi .pyo . Zobacz moją odpowiedź.
Wilfred Hughes,

Użyłem kodu z zaakceptowanej odpowiedzi i zadziałało, ale te polecenia są krótsze i proste
Dap

3
-name '*.py?'dołączyć.pyo, .pyc,...
cdosborn,

2
UPEWNIJ SIĘ, że - usuń to ostatnia rzecz w poleceniu. Przypadkowo umieściłem -delete zaraz po znalezieniu. Usunął wszystko!
thinkanotherone

85

W aktualnej wersji debiana masz pycleanskrypt, który jest w python-minimalpakiecie.

Użycie jest proste:

pyclean .

34
Warto zauważyć, że pyclean wydaje się usuwać tylko pliki .pyc, dla których istnieje odpowiedni plik .py (przynajmniej w moim systemie - ubuntu 12.10.) Oznacza to, że nie jest to bardzo pomocne w sytuacjach, gdy plik źródłowy został usunięty i chcesz aby usunąć resztki plików .pyc.
tigerFinch

@holms pyclean(i teraz py3clean) pochodzą z pakietu Debian, a zatem nie są w RHEL.
duozmo

83

Dodaj do ~/.bashrc:

pyclean () {
        find . -type f -name "*.py[co]" -delete
        find . -type d -name "__pycache__" -delete
}

Spowoduje to usunięcie wszystkich plików .pyc i .pyo oraz __pycache__katalogów. Jest również bardzo szybki.

Użycie jest po prostu:

$ cd /path/to/directory
$ pyclean

find . -type d -name "__pycache__" -deleteczęsto ostrzega o brakującej ścieżce, ponieważ widocznie zawartość zostanie dodana do kolejki przed usunięciem folderu. 2>/dev/nullpowinien to naprawić.
Szalony fizyk

53

Jeśli używasz bash> = 4.0 (lub zsh)

rm **/*.pyc

Zauważ, że */*.pyczaznacza wszystkie .pycpliki w bezpośrednich podkatalogach pierwszego poziomu, podczas gdy **/*.pycrekurencyjnie skanuje całe drzewo katalogów. Na przykład foo/bar/qux.pyczostanie usunięty przez, rm **/*.pycale nie przez */*.pyc.

Opcje powłoki globstar muszą być włączone. Aby włączyć globstar:

shopt -s globstar

i aby sprawdzić jego status:

shopt globstar

1
Jaka jest różnica w bieganiu rm **/*.pycvs rm */*.pyc? (Wydaje się, że ten ostatni działa dla mnie lokalnie.)
Taylor Edmiston

1
@TaylorEdmiston rm */*.pycusunie wszystkie .pycpliki we wszystkich podkatalogach głębokości 1. rm **/*.pycusunie wszystkie .pycpliki we wszystkich podkatalogach głębokości 0+
Adam Stewart

@AdamStewart Dziękujemy za dodanie tego. Dla innych, którzy natknęli się na ten wątek, miałem problem polegający na tym, że bash Apple'a dostarczany z OS X nie zawiera globstar ( **działa więc tak , jak *gdy zamiast tego uruchamia się, a uruchamianie shopt globstargeneruje błąd).
Taylor Edmiston

30

Użyłem do tego aliasu:

$ which pycclean

pycclean is aliased to `find . -name "*.pyc" | xargs -I {} rm -v "{}"'

12
W obecnym debianie jest to pyclean.
jb.

7
Nie radzi sobie to dobrze z białymi spacjami w nazwach plików. Powinieneś użyć find -print0i xargs -0zamiast.
r3m0t

2
Dlaczego chcesz mieć kod Pythona ze spacjami w nazwach plików / folderów? Czy to jest syntaktycznie legalne?
coredumperror

@CoreDumpError, tak, w rzeczywistości w Windows Python instaluje się w katalogu ze spacjami („Program Files”).
Paul Draper,

Interpreter Pythona może instalować się tam domyślnie, ale nie jest to dobre miejsce na umieszczenie kodu . Ponadto z pewnością nie chcesz, aby folder Program Files był częścią struktury pakietu, dlatego ostrożnie podchodziłem do składni.
coredumperror

24

Dla użytkowników systemu Windows:

del /S *.pyc

Umieszczenie tego w skrypcie wsadowym sprawia, że ​​wszystko jest super łatwe. Dzięki.
Nick Gotch

A jeśli korzystasz z Powershell, można tego użyć z „cmd” -> Uruchom polecenie -> „exit”.
np8

18
find . -name '*.pyc' -print0 | xargs -0 rm

Znalezienie rekurencyjnie szuka plików * .pyc. Xargs pobiera tę listę nazw i wysyła ją do rm. -Print0 i -0 nakazują dwóm poleceniom rozdzielenie nazw plików znakami null. Pozwala to na poprawną pracę na nazwach plików zawierających spacje, a nawet na nazwach plików zawierających nowy wiersz.

Rozwiązanie z -exec działa, ale obraca nową kopię rm dla każdego pliku. W wolnym systemie lub z dużą liczbą plików, to zajmie zbyt długo.

Możesz również dodać kilka dodatkowych argumentów:

find . -iname '*.pyc' -print0 | xargs -0 --no-run-if-empty  rm

iname dodaje rozróżnianie wielkości liter, takie jak * .PYC. Polecenie no-run-if-empty zapobiega wyświetlaniu błędu z rm, jeśli nie masz takich plików.


16
$ find . -name '*.pyc' -delete

To jest szybsze niż

$ find . -name "*.pyc" -exec rm -rf {} \;

11

Ponadto, ludzie zwykle chcą, aby usunąć wszystkie *.pyc, *.pyopliki i __pycache__katalogi rekursywnie w bieżącym katalogu.

Komenda:

find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf

To dobra odpowiedź, ale proste rozwiązanie w języku Python byłoby wieloplatformowe i dlatego jest preferowane. Choć osobiście nie dbam o windows prawdopodobnie połowa populacji żyje w Pythonie na Windows - a find, grepa przyjaciele nie tam pracują.
Peterino

Robią to, jeśli zainstalujesz oprzyrządowanie. Polecam każdemu użytkownikowi interfejsu CLI systemu Windows, aby zrobił to w celu ułatwienia wzajemnej zgodności: superuser.com/questions/168202/…
DylanYoung

8

Aby wrzucić inny wariant do miksu, możesz również użyć cudzysłowów w następujący sposób:

rm `find . -name *.pyc`

5
Ma to niewielką wadę polegającą na niepowodzeniu, jeśli jest zbyt wiele dopasowań, ponieważ będzie zbyt wiele argumentów do przekazania rm.
chepner,


7

pełny rekurencyjny

ll **/**/*.pyc
rm **/**/*.pyc

Ciekawe, jak to porównać do odpowiedzi Andy'ego i Billa?
Austin Henley,

3
Jeden zestaw **jest redundantny i zgodnie z d0kodpowiedzią, musisz mieć włączoną globstar w bash 4+, aby działało to zgodnie z przeznaczeniem. tzn. zrób shopt -s globstarlub miej to w jednym z twoich bashów. akta.
Przywróć Monikę, proszę,

1
llJest również powszechnie aliasowany do czegoś podobnego ls -l, ale tak naprawdę nie jest poleceniem ani urządzeniem przenośnym. Aby rekurencyjnie wyświetlić wszystkie .pycpliki ., powinieneś zamiast tego zrobić coś echo **/*.pycz włączoną globstar
Przywróć Monikę Proszę

3

Pierwszy bieg:

find . -type f -name "*.py[c|o]" -exec rm -f {} +

Następnie dodaj:

export PYTHONDONTWRITEBYTECODE=1

Do ~ / .profile


3

jeśli nie chcesz już .pyc, możesz użyć tej pojedynczej linii w terminalu:

export PYTHONDONTWRITEBYTECODE=1

Jeśli zmienisz zdanie:

unset PYTHONDONTWRITEBYTECODE

2

rm -rpowraca do katalogów, ale tylko do katalogów, które podajesz rm. Spowoduje to również usunięcie tych katalogów. Jednym z rozwiązań jest:

for i in $( find . -name *.pyc )
do
  rm $i
done

findznajdzie rekursywnie wszystkie pliki * .pyc w bieżącym katalogu, a forpętla przejdzie przez listę znalezionych plików, usuwając każdy z nich.


Ten działa, chociaż muszę go umieścić w pliku .sh i uruchomić to (co jest w porządku,
użyję

Uważam, że umieszczenie tego wszystkiego w jednym wierszu oddzielonym znakiem „;” powinno pozwolić na uruchomienie go w powłoce. Ale kiedy wpisuję to w bash, bash czeka na „zrobione” na końcu, aby cokolwiek wykonać ...
Chris Lutz

To okropny antypattern (i bardzo powszechny, chciałbym, żeby mógł zniknąć): łamie się w nazwach plików zawierających spacje lub znaki globu. I nie ma sensu findze swoim -execorzeczeniem: find . -name '*.pyc' -exec rm {} +(ładniejszy, krótszy, bezpieczniejszy, solidny, wydajniejszy).
gniourf_gniourf


1

Możesz biegać find . -name "*.pyc" -type f -delete.

Ale używaj go ostrożnie. Uruchom najpierw, find . -name "*.pyc" -type faby zobaczyć dokładnie, które pliki chcesz usunąć.

Ponadto upewnij się, że -delete jest ostatnim argumentem w twoim poleceniu. Jeśli umieścisz go przed argumentem -name * .pyc, usunie wszystko.


1

Jeśli chcesz usunąć wszystkie pliki .pyc z folderu projektu.

Po pierwsze masz

cd <path/to/the/folder>

następnie znajdź cały plik .pyc i usuń.

find . -name \*.pyc -delete
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.