Как я могу рекурсивно удалить все файлы определенного расширения в текущем каталоге?

531

Как безопасно удалить все файлы с определенным расширением (например .bak) из текущего каталога и всех подпапок с помощью одной командной строки? Просто я боюсь использовать, rmпотому что я однажды использовал это неправильно, и теперь мне нужен совет.

user216038
источник

Ответы:

840

Вам даже не нужно использовать rmв этом случае, если вы боитесь. Используйте find:

find . -name "*.bak" -type f -delete

Но используйте его с осторожностью. Запустите сначала:

find . -name "*.bak" -type f

чтобы увидеть, какие именно файлы вы будете удалять.

Также убедитесь, что -deleteэто последний аргумент в вашей команде. Если вы поставите его перед -name *.bak argument, он удалит все .

Смотрите man findи man rmдля получения дополнительной информации, а также увидеть этот связанный вопрос по SE:

Раду Рэдяну
источник
Чем это отличается от rm *.bak?
Саянтанхан
10
@ Bolt64 Вы rm *.bakне будете работать для подкаталогов.
Раду Рэдяну
С настройками по умолчанию rm *.bakбудут удалены только все файлы, заканчивающиеся на .bak в текущем каталоге. Чтобы также выполнять действия в подкаталогах, которые вам либо понадобились для работы с глобусами, используйте опцию -r или пример поиска.
Hennes
9
@Hennes Будь осторожен с rm -r *.bak! Он также удаляет каталоги, заканчивающиеся .bakвсем их содержимым.
Раду Рэдяну
37
Убедитесь, что -deleteэто последний аргумент в вашей команде. Если вы поставите его перед -name *.bakаргументом, он удалит все.
Майкл
40
find . -name "*.bak" -type f -print0 | xargs -0 /bin/rm -f
lokers
источник
1
Добро пожаловать в Askubuntu! Хотя это совершенно правильный ответ, я не думаю, что есть преимущество в использовании этого вместо -deleteфлага find. Дополнительную информацию можно найти в записи руководства GNU по удалению файлов с помощью команды find .
Glutanimate
2
Вы, вероятно, правы, это просто альтернативное решение, возможно, более сырое;)
lokers
11
Это не просто альтернатива, а пример того, как другие команды могут быть объединены вместе с каналом '|'. +1
Борис Павлович
13
Эти альтернативные решения работают в других средах, в которых отсутствует -delete (например, cygwin)
ciriarte
2
Я думаю, что это лучший ответ здесь.
Лео Леопольд Герц
33

Сначала запустите команду shopt -s globstar. Вы можете запустить это в командной строке, и это будет действовать только в этом окне оболочки. Вы можете положить его в свой .bashrc, и тогда все вновь запущенные снаряды подберут его. Результатом этой команды является **/рекурсивное создание файлов совпадений в текущем каталоге и его подкаталогах (по умолчанию **/означает то же самое, что и */: только в непосредственных подкаталогах). Затем:

rm **/*.bak

(или gvfs-trash **/*.bakили что у тебя).

жилль
источник
21

Удаление файлов для меня не то, что вы должны использовать rmдля. Вот альтернатива:

sudo apt-get install gvfs     # install a tool that allows you to put stuff in the trash
alias "trash"="gvfs-trash"    # you can also put this in .bash_aliases or simply use the command without alias
trash *.bak                   # trash the files (thus moving them to the trash bin)

Как утверждает Флимм в комментариях:

Пакет trash-cliделает то же самое, что и gvfs-trashбез зависимости от gvfs.

Так:

sudo apt-get install trash-cli

Вам не нужно создавать псевдоним для этого, потому что trash-cliпакет предоставляет команду trash, которая делает то, что мы хотим.

Как поясняет Элия Каган в подробных комментариях, вы также можете сделать это рекурсивным использованием find. В этом случае вы не можете использовать псевдоним, поэтому команды ниже предполагают, что вы установили trash-cli. Я суммирую комментарии Элии:

Эта команда находит и отображает все .bakфайлы и символические ссылки в любом месте текущего каталога или его подкаталогов или ниже.

find . -name '*.bak' -xtype f

Для того, чтобы удалить их, добавьте к -execс trashкомандой:

find . -name '*.bak' -xtype f -exec trash {} +

-xtype fвыбирает файлы и символические ссылки на файлы, но не папки. Чтобы также удалить папки .bak, удалите эту часть и используйте ее -execdir, чтобы избежать cannot trash non-existentошибок для .bakфайлов внутри .bakкаталогов:

find . -name '*.bak' -execdir trash {} +
don.joey
источник
4
«Не используйте rmдля удаления вещи» является спорным утверждением , но я должен согласиться , что часто разумнее использовать что - то , что позволит вам отменить вещи.
Оли
2
Пакет trash-cliделает то же самое, что и gvfs-trashбез зависимости от gvfs.
Flimm
Я отредактировал это в ответе, в следующий раз не стесняйтесь делать редактирование самостоятельно.
don.joey
@ don.joey Этот ответ, кажется, говорит, find . -name "*.bak" -type fчто trash *.bakудаляет. Это действительно то, что вы имеете в виду? Вы можете перемещать каталоги в корзину с помощью trashили gvfs-trash, но trash *.bakперемещать будут только файлы и каталоги, чьи имена заканчиваются .bakи которые находятся непосредственно в текущем каталоге. Оболочка расширяется *.bak, поэтому trash *.bakне влияет на .bakфайлы в подкаталогах, которые сами не названы .bak.
Элия ​​Каган,
1
@ don.joey Да ls *.bak(что, я думаю, вы имеете в виду) перечисляет, что trash *.bakмусор. find . -name '*.bak' -xtype f -exec trash {} +удаляет все .bakфайлы в любом месте под .. Он не может использовать псевдоним, поэтому установите trash-cliили напишите gvfs-trashвместо этого. Вот пример. -xtype fвыбирает файлы и символические ссылки на файлы, но не папки. Для удаления .bak папок тоже используйте find . -name '*.bak' -execdir trash {} +, чтобы избежать cannot trash non existentошибок для .bakфайлов внутри .bakкаталогов. Пожалуйста, не стесняйтесь использовать все это в своем ответе.
Элия ​​Каган,
5

Если вы хотите удалить из текущей папки все файлы определенного типа, но только 1 «глубокая»:

find . -maxdepth 2 -name "*.log" -type f -delete

-maxdepth 2, потому что текущий каталог " . " считается первой папкой.

Hypocritus
источник
1

Быстрый ответ:

  • Удалить все файлы с рассматриваемым именем или постфиксом рекурсивно:

    find . -name '*.pyc' -type f -delete

  • Удалить все каталоги с рассматриваемым именем рекурсивно:

    find ~ -path '*/__pycache__/*' -delete‍‍‍
    find ~ -type d -name '__pycache__' -empty -delete‍‍‍
    

    Несколько менее строго контролируется, но в одной строке:

    find ~ -path '*/__pycache__*' -delete
    

[ ПРИМЕЧАНИЕ ]:

dопция каталога и опция fфайла.

Беньямин Джафари
источник
0

Если вы находитесь в git-репо, вы можете использовать:

git clean -fdx

Это удаляет неотслеживаемые файлы и файлы в .gitignore.

Васанта Ганеш К
источник