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

491

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

 rm -r *.pyc

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

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

16 ответов

868
Лучший ответ
find . -name "*.pyc" -exec rm -f {} \;

как указано в комментариях, вы также можете использовать действие -delete

find . -name \*.pyc -delete
  • 0
    Я проверил оба из них. Каталоги, вероятно, были слишком малы, чтобы быть значимыми, но это получилось быстрее, чем у меня, что я и ожидал, так как мой должен собрать список, а затем выполнить итерацию по нему, в то время как ваш удаляет каждый элемент по мере его обнаружения.
  • 346
    Find имеет встроенное действие "-delete", так что вы можете просто find . -name \*.pyc -delete
Показать ещё 7 комментариев
817

find . -name '*.pyc' -delete

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

  • 92
    +1. Эта команда чувствует себя намного безопаснее, чем принятая в настоящее время Биллом Ящерицей. Любая команда с rm -rf немного страшна. :)
  • 13
    Также учтите, что здесь «-r» совершенно не нужен. "rm -f" вполне достаточно.
Показать ещё 7 комментариев
71

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

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

pyclean .
  • 32
    Стоит отметить, что pyclean, по-видимому, удаляет только файлы .pyc, для которых есть соответствующий файл .py (по крайней мере, в моей системе - ubuntu 12.10.) Это означает, что это не очень полезно в ситуациях, когда исходный файл был удален, и вы хотите очистить остатки .pyc файлов.
  • 2
    Не работает на RHEL, такой команды нет.
Показать ещё 1 комментарий
57

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

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

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

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

$ cd /path/to/directory
$ pyclean
  • 0
    find . -type d -name "__pycache__" -delete часто find . -type d -name "__pycache__" -delete предупреждение о пропущенном пути, поскольку очевидно, что содержимое будет добавлено в очередь до удаления папки. 2>/dev/null должен это исправить.
46

Если вы используете 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+
Показать ещё 1 комментарий
30

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

$ which pycclean

pycclean is aliased to `find . -name "*.pyc" | xargs -I {} rm -v "{}"'
  • 12
    В текущем Debian это Pyclean.
  • 6
    Это не касается пробелов в именах файлов. xargs -0 этого вы должны использовать find -print0 и xargs -0 .
Показать ещё 3 комментария
16
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, если у вас нет таких файлов.

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

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

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

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

rm `find . -name *.pyc`
  • 4
    Это имеет небольшой недостаток: если слишком много совпадений, так как будет слишком много аргументов для передачи в rm .
6

Расширение Django

Примечание. Этот ответ очень специфичен для проекта Django, который уже использовал Расширение Django.

python manage.py clean_pyc

Реализация может быть просмотрена в исходном коде.

6

полная рекурсивная

ll **/**/*.pyc
rm **/**/*.pyc
  • 0
    Интересно, как это соотносится с ответами Энди и Билла?
  • 3
    Один набор ** избыточен, и, как и в d0k , вы должны включить globstar в bash 4+, чтобы это работало как задумано. то есть сделайте shopt -s globstar или shopt -s globstar это в одном из ваших источников. файлы.
Показать ещё 2 комментария
5

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

del /S *.pyc
  • 0
    Помещение этого в пакетный скрипт делает все очень просто. Благодарю.
4

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

Команда:

find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
  • 0
    Это хороший ответ, но простое решение Python будет кроссплатформенным и, следовательно, предпочтительным. Хотя лично мне наплевать на Windows, вероятно, половина пользователей Python живет на Windows - и find , что grep и друзья там не работают.
3

Первый запуск:

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

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

export PYTHONDONTWRITEBYTECODE=1

To ~/.profile

2
find . -name "*.pyc"|xargs rm -rf
2

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

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

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

  • 0
    Это работает, хотя я должен поместить его в файл .sh и запустить его (что меня устраивает, я буду использовать эту команду более одного раза)
  • 0
    Я считаю, что если поместить все это в одну строку, разделенную символом ';, то это позволит вам запустить его в оболочке. Но когда я набираю это в bash, bash ждет, пока "done" в конце ничего не выполнит ...
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню