Як я можу рекурсивно видаляти всі файли певного розширення в поточному каталозі?


531

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

Відповіді:


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?
sayantankhan

10
@ Bolt64 Ваша rm *.bakробота не буде працювати в підкаталогах.
Radu Rădeanu

Якщо налаштування за замовчуванням rm *.bakвидалять лише всі файли, що закінчуються .bak у поточному каталозі. Щоб також робити речі у підкаталогах, які вам потрібні, щоб поспілкуватися з глобусами, скористайтеся опцією -r або використовуйте приклад пошуку.
Геннес

9
@Hennes Будь обережним rm -r *.bak! Він також видаляє каталоги, що закінчуються .bakусім їхнім вмістом.
Radu Rădeanu

37
Переконайтеся, що -deleteце останній аргумент у вашій команді. Якщо ви поставите його перед -name *.bakаргументом, він видалить усе.
Майкл

40
find . -name "*.bak" -type f -print0 | xargs -0 /bin/rm -f

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 {} +

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, оскільки поточний каталог " . " вважається першою папкою.


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 repo, ви можете використовувати:

git clean -fdx

Це видаляє незатрековані файли та файли в .gitignore.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.