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

678

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

 rm -r *.pyc

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

Teifion
источник
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
d0k
источник
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
HAKI
источник
Помещение этого в пакетный скрипт делает все очень просто. Спасибо.
Ник Готч
И если вы используете 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 {} \;
Moxdata
источник
11

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

Команда:

find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
Mithril
источник
Это хороший ответ, но простое решение 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
romuloigor
источник
Интересно, как это соотносится с ответами Энди и Билла?
Остин Хенли,
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, он удалит все.

gpap
источник
1

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

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

cd <path/to/the/folder>

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

find . -name \*.pyc -delete
Гириш Вас
источник