Как удалить все файлы .pyc из проекта?


678

Я переименовал некоторые файлы в довольно большом проекте и хочу удалить файлы .pyc, которые они оставили. Я попробовал скрипт bash:

 rm -r *.pyc

Но это не повторяется через папки, как я думал, что будет. Что я делаю неправильно?


11
Это не работает, потому что в UNIX глобусы расширяются оболочкой, а не выполняемой программой. Если в текущем каталоге есть a.pyc и b.pyc, а каталоги foo и bar rmбудут вызываться с аргументами [-r, a.pyc, b.pyc].
Эфимент

1
если вы беспокоитесь о том, чтобы передать свой код другим людям, вы можете просто добавить его в .gitignore, **/*.pycтогда вам больше не придется беспокоиться об этом
bubakazouba

Ответы:


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

385
Find имеет встроенное действие «-delete», так что вы можете сделать это простоfind . -name \*.pyc -delete
Christoffer

51
Самое главное, если это компьютер разработчика, вы можете установить PYTHONDONTWRITEBYTECODE = True, и вам больше никогда не придется делать это снова. Смотрите: этот ответ .
mlissner

5
Вы не цитируете {}. Что произойдет, если случайно разбить слово и удалить промежуточный путь, который называется как фрагмент пути, который вы нашли?
Robottinosino

20
-deleteне является частью спецификации POSIX и не гарантированно существует во всех реализациях find.
chepner

7
Если вы напуганы - что может быть хорошо - сделайте первый проход с -exec echo {}, или - если вы очень напуганы - используйте rm -i {}, который спрашивает вас каждый раз, или rm - v {}, чтобы вы увидели, что Вы удаляете.
Жан

1021

find . -name '*.pyc' -delete

Конечно, самый простой.


21
Если ваша версия findподдерживает -delete; это не часть стандарта POSIX.
chepner

4
Это игнорирует .pyo файлы и __pycache__каталоги. Смотри мой ответ.
Уилфред Хьюз

Я использовал код из принятого ответа, и он работал, но эти команды короче и проще
Dap

3
-name '*.py?'включить.pyo, .pyc,...
cdosborn

2
УБЕДИТЕСЬ, что удаление - это последнее, что есть в команде. Я случайно поставил -delete сразу после поиска. Он удалил все!
thinkanotherone

85

В текущей версии Debian у вас есть pycleanскрипт, который находится в python-minimalпакете.

Использование простое:

pyclean .

34
Стоит отметить, что pyclean, по-видимому, удаляет только файлы .pyc, для которых есть соответствующий файл .py (по крайней мере, в моей системе - ubuntu 12.10.) Это означает, что это не очень полезно в ситуациях, когда исходный файл был удален, и вы хотите очистить остатки .pyc файлов.
tigerFinch

@holms pyclean(и сейчас py3clean) происходят из пакета Debian и, следовательно, не находятся в RHEL.
duozmo

83

Добавьте к вашему ~/.bashrc:

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

Это удаляет все файлы .pyc и .pyo, а также __pycache__каталоги. Это также очень быстро.

Использование просто:

$ cd /path/to/directory
$ pyclean

find . -type d -name "__pycache__" -deleteчасто выдает предупреждение об отсутствующем пути, поскольку, очевидно, содержимое будет добавлено в очередь до удаления папки. 2>/dev/nullдолжен это исправить.
Безумный физик

53

Если вы используете bash> = 4.0 (или zsh)

rm **/*.pyc

Обратите внимание, что */*.pycвыбираются все .pycфайлы в непосредственных подкаталогах первого уровня, а **/*.pycрекурсивно сканируется все дерево каталогов. Например, foo/bar/qux.pycбудет удален, rm **/*.pycно не удален */*.pyc.

Параметры оболочки globstar должны быть включены. Чтобы включить globstar:

shopt -s globstar

и проверить его статус:

shopt globstar

1
Какая разница в беге rm **/*.pycпротив rm */*.pyc? (Последний, похоже, работал на меня локально.)
Тейлор Эдмистон

1
@TaylorEdmiston rm */*.pycудалит все .pycфайлы во всех подкаталогах глубины 1. Удалит rm **/*.pycвсе .pycфайлы во всех подкаталогах глубины 0+
Адам Стюарт,

@AdamStewart Спасибо за добавление этого. Что касается других, спотыкающихся в этой теме, то проблема, с которой я столкнулся, заключалась в том, что в пакет Apple, поставляемый с OS X, не входит globstar (поэтому он **работает так же, как *при запуске, а запуск при запуске shopt globstarвыдает ошибку).
Тейлор

30

Я использовал псевдоним для этого:

$ which pycclean

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

12
В текущем Debian это Pyclean.
JB.

7
Это не касается пробелов в именах файлов. Вы должны использовать find -print0и xargs -0вместо этого.
r3m0t

2
Почему вы хотите иметь код Python с пробелами в именах файлов / папок? Это синтаксически законно?
coredumperror

@CoreDumpError, да, на самом деле в Windows Python устанавливается в каталог с пробелами («Program Files»).
Пол Дрейпер

По умолчанию интерпретатор Python может быть установлен там, но вряд ли это хорошее место для размещения вашего кода . Кроме того, вы, конечно, не хотели бы, чтобы папка Program Files была частью структуры вашего пакета, поэтому я с осторожностью относился к синтаксису.
coredumperror

24

Для пользователей Windows:

del /S *.pyc

Помещение этого в пакетный скрипт делает все очень просто. Спасибо.
Ник Готч

И если вы используете Powershell, это можно использовать с помощью команды «cmd» -> Run -> «exit».
np8

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

Поиск рекурсивно ищет файлы * .pyc. Xargs берет этот список имен и отправляет его в rm. -Print0 и -0 говорят двум командам разделять имена файлов нулевыми символами. Это позволяет ему корректно работать с именами файлов, содержащими пробелы, и даже с именем файла, содержащим новую строку.

Решение с -exec работает, но оно раскручивает новую копию rm для каждого файла. На медленной системе или с большим количеством файлов это займет слишком много времени.

Вы также можете добавить еще пару аргументов:

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

iname добавляет нечувствительность к регистру, как * .PYC. No-run-if-empty не позволяет получить ошибку от rm, если у вас нет таких файлов.


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

Это быстрее чем

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

11

Кроме того, люди , как правило , хотят , чтобы удалить все *.pyc, *.pyoфайлы и __pycache__каталоги рекурсивно в текущем каталоге.

Команда:

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

Это хороший ответ, но простое решение Python будет кроссплатформенным и, следовательно, предпочтительным. Хотя, лично я не забочусь о Windows , вероятно , половина жизни населения Python на Windows - и find, grepи друзья не работают там.
Петерино,

Они делают, если вы установите инструмент. Я бы порекомендовал каждому пользователю CLI для Windows сделать это для облегчения кросс-совместимости: superuser.com/questions/168202/…
DylanYoung

8

Просто чтобы добавить другой вариант в микс, вы также можете использовать обратные кавычки:

rm `find . -name *.pyc`

5
Это имеет небольшой недостаток: если слишком много совпадений, так как будет слишком много аргументов для передачи rm.
chepner


7

полный рекурсивный

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

Интересно, как это соотносится с ответами Энди и Билла?
Остин Хенли,

3
Один набор **является избыточным, и, как и в d0kответе, вы должны включить globstar в bash 4+, чтобы это работало как задумано. то есть делай shopt -s globstarили имей это в одном из своих источников. файлы.
Восстановите Монику, пожалуйста,

1
Также llобычно псевдоним для чего-то вроде ls -l, но на самом деле это не команда или портативный. Таким образом, для рекурсивного перечисления всех .pycфайлов ., вы должны вместо этого сделать что-то вроде echo **/*.pycс globstar
Восстановите Monica Please

3

Первый забег:

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

Затем добавьте:

export PYTHONDONTWRITEBYTECODE=1

В ~ / .profile


3

если вы больше не хотите .pyc, вы можете использовать эту строку в терминале:

export PYTHONDONTWRITEBYTECODE=1

если вы передумаете:

unset PYTHONDONTWRITEBYTECODE

2

rm -rвозвращается в каталоги, но только в каталоги, которые вы даете rm. Это также удалит эти каталоги. Одним из решений является:

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

findвсе файлы * .pyc будут рекурсивно найдены в текущем каталоге, и forцикл будет перебирать список найденных файлов, удаляя каждый из них.


Это работает, хотя я должен поместить его в файл .sh и запустить его (что хорошо для меня, я буду использовать эту команду более одного раза)
Teifion

Я считаю, что если поместить все это в одну строку, разделенную символом ';', вы должны запустить его в оболочке. Но когда я набираю это в bash, bash ждет, когда в конце «выполнено», чтобы выполнить что-либо ...
Крис Латс

Это ужасный антипаттерн (и очень распространенный, хотелось бы, чтобы он исчез): он разрывается с именами файлов, содержащими пробелы или символы глобуса. И findс его -execпредикатом он упускает смысл : find . -name '*.pyc' -exec rm {} +(лучше, короче, безопаснее, надежнее, эффективнее).
gniourf_gniourf


1

Ты можешь бежать find . -name "*.pyc" -type f -delete.

Но используйте его с осторожностью. Беги первымfind . -name "*.pyc" -type f чтобы увидеть, какие именно файлы вы будете удалять.

Кроме того, убедитесь, что -delete является последним аргументом в вашей команде. Если вы поставите его перед аргументом -name * .pyc, он удалит все.


1

Если вы хотите удалить все файлы .pyc из папки проекта.

Во-первых, у вас есть

cd <path/to/the/folder>

затем найдите все файлы .pyc и удалите.

find . -name \*.pyc -delete
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.