Рекурсивно видаляйте файли


140

Хтось має рішення видалити ті примхливі файли ._ та .DS_Store, які ви отримуєте після переміщення файлів з Mac на сервер Linux?

вказати стартовий каталог і відпустити його? як / var / www / html / down ...


Хоча це не є дублікатом ІМО, ви повинні дивитися на це: stackoverflow.com/questions/1280429 / ...
Grundlefleck

Хоча не те, про що ви просите. Я б заперечував, що це краще рішення: unix.stackexchange.com/questions/9665/…
Віктор,

Відповіді:


169

перейдіть до каталогу та скористайтеся:

find . -name ".DS_Store" -print0 | xargs -0 rm -rf
find . -name "._*" -print0 | xargs -0 rm -rf

Не перевірено, спробуйте їх без xargs спочатку!

Ви можете замінити період після пошуку, директорією, а не спочатку переходити до каталогу.

find /dir/here ...

2
Я знаю, його питання не задавав цього питання, але я ніколи не пам'ятаю: чи ваш приклад обробляє назви файлів з пробілами?
Grundlefleck

4
Так, для цього потрібні print0 і -0 до xargs. Зазвичай він не буде обробляти пробіли правильно, проте з print0 він надрукує ім'я файлу з нульовим символом в кінці рядка, який xarg з -0 потім використовуватиме для передачі повного шляху до xargs, не маючи шансу мати пробіл використовуючи другий чи третій параметр команди rm, що може бути дуже поганим!
X-Istence

7
@X: новіші findutils підтримують -deleteдію, яка може скоротити це. @JT: Цей пошук проводиться рекурсивно під .. Залежить від того, скільки файлів і підкаталогів існує ... Ви не можете просто заборонити завантажувати їх?
ефемієнт

1
Використання -rпрапора (рекурсивного) в цьому випадку не рекомендується, оскільки ви не хочете видаляти жодні каталоги ..
Daniel Zohar

2
@IlmariKaronen: хороший момент. Не command rmбуло б кращим (тобто більш прямим) рішенням? (Під "прямим" я маю на увазі, що він розглядає конкретно проблему, що існує, і більше нічого, тому менше шансів на те, щоб виникнути небажані побічні ефекти, а також буде більш зрозумілим для тих, хто повинен підтримувати код пізніше.)
іконоборство


86

Більш нові підтримують файли -delete, тому:

find . -name ".DS_Store" -delete

Додати, -printщоб отримати також список видалень.

Команда працюватиме для вас, якщо у вас є сучасна система POSIX, я вважаю. Принаймні, це працює для мене в OS X 10.8 і працює для інших, хто протестував його на macOS 10.12 (Mojave).

Подяка @ephemient у коментарі до повідомлення @ X-Istence (він вважав, що це досить корисно, щоб гарантувати власну відповідь).


1
Працює ще в OSX 10.6.
хосс

3
Найпростіше і найпростіше рішення, +1!
ліміст

6
@OneOfOne: як говориться в моєму коментарі, я отримав це від @ ephemient. Як початківець, що базується, я знайшов ваше (можливо, більш правильне) рішення набагато менш читабельним та корисним. Вони можуть бути функціонально однаковими, але я вважаю, що цей синтаксис забезпечує більшу чіткість.
rattray

1
'.' не потрібно, оскільки findза замовчуванням рекурсує у поточний робочий каталог.
Том Расселл

У нових версіях програми каталог може бути опущений, і це буде мати на увазі поточну робочу директорію ( wikipedia ). Вам все ще потрібно .на macOS 10.12 (Сьєрра).
Дем Пілафіян

18

Проста команда:

rm `find ./ -name '.DS_Store'` -rf
rm `find ./ -name '._'` -rf

Удачі!


1
Це чудово працює. АЛЕ слово обережності, я щойно використав цю rm -i знахідку ./ -name '* py'` -rf , which did NOT prompt me to delete files. you will need to take it on the end (i.e. -rfi`). Слава богу за мій резервний сценарій.
ryanjdillon

1
Якщо файлів занадто багато, це помилка з помилкою:-bash: /bin/rm: Argument list too long
Віктор,

12
cd /var/www/html && find . -name '.DS_Store' -print0 | xargs -0 rm
cd /var/www/html && find . -name '._*' -print0 | xargs -0 rm

2
Мені це сподобалось краще просто тому, що "rm" не має "-r", що не потрібно для цього конкретного завдання.
lotoffreetime

6

Ви можете перейти на zsh замість bash. Це дозволяє вам використовувати ** для зіставлення файлів у будь-якому місці дерева дерева:

$ rm /var/www/html/**/_* /var/www/html/**/.DS_Store

Ви також можете комбінувати їх так:

$ rm /var/www/html/**/(_*|.DS_Store)

У Zsh є безліч інших функцій, яких бракує, але лише одна варта переключитися. Він доступний у більшості (мабуть, усіх) Linux-дистрибутивах, а також у cygwin та OS X.

Додаткову інформацію можна знайти на сайті zsh .


1
Можлива проблема: оскільки ви не використовуєте xargs, ви можете зіткнутися з обмеженням довжини аргументу командного рядка. Також Bash 4 також підтримує **:-) (хоча це не за замовчуванням, shopt -s globstarпотрібно встановити)
ефеміент

4
find . -name "FILE-TO-FIND"-exec rm -rf {} \;

Використання exec для кожного знайденого файлу не є швидким. Швидше знайти роздрукувати їх, а потім використовувати xargs, щоб викликати rm один раз.
X-Istence

3
Однак якщо у вас є такий, findщо підтримує його, +схожий на xargs: find . -name "FILE-TO-FIND" -exec rm -rf {} +- (також ви пропустите пробіл раніше -exec)
Призупинено до подальшого повідомлення.

3
у нас ніколи не було речей xargs. І нам довелося піти до школи, в гору обома напрямками .......
Мартін Беккет

3

Приклад для видалення "Thumbs.db" рекурсивно;

find . -iname "Thumbs.db" -print0 | xargs -0 rm -rf

Перевірка:

find . -iname "Thumbs.db"

Тепер це не повинно відображати жодної записи із "Thumbs.db" всередині поточного контуру.


Будь ласка , переконайтеся , що ваша відповідь друкує список того , що видаляється і пояснити , чому хтось - то може знадобитися використовувати xargsі print0замість exec(є причини).
Джош Хабдас


2

якщо у вас є Bash 4.0 ++

#!/bin/bash
shopt -s globstar
for file in /var/www/html/**/.DS_Store /var/www/html/**/._ 
do
 echo rm "$file"
done

2
Запуск нової копії rm для кожного файлу є марним.
X-Istence

2
@ X-Istence передчасна оптимізація марнотратна
Lucina

Запропонований за оригінальність та використання новітніх баш-інновацій.
Джош Хабдас

1

Кілька речей, які слід зазначити:

'-delete' не є рекурсивним. Отже, якщо .TemvremeItems (папка) містить файли, команда не працює.

Існує дуже багато цих примхливих файлів, створених Mac: .DS_Store ._. DS_Store .TemvremeItems .apdisk

Ця одна команда стосується всіх них. Зберігає від запуску пошук знову і знову для кількох матчів.

find /home/foo \( -name '.DS_Store' -or -name '._.DS_Store' -or -name '._*' -or -name '.TemporaryItems' -or -name '.apdisk' \) -exec rm -rf {} \;

0

Це також працює:

sudo rm -rf 2018-03-*

тут ваші видалення файлів з іменами формату 2018-03- (щось інше)

не ускладнювати


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