rm -rf всі файли та всі приховані файли без. & .. помилка


82

rm -rf /some/path/* видаляє всі не приховані файли у цьому dir (та підкаталогах).

rm -rf /some/path/.* видаляє всі приховані файли в цьому dir (але не підкаталоги), а також видає такі помилки / попередження:

rm: cannot remove directory: `/some/dir/.'
rm: cannot remove directory: `/some/dir/..'

Який правильний спосіб видалити всі приховані та не приховані файли та папки рекурсивно в цільовому каталозі, не отримуючи попередження / помилку про .та ..?

Відповіді:


39

Ви завжди можете надсилати повідомлення про помилки на /dev/null

rm -rf /some/path/.* 2> /dev/null

Ви також могли просто

rm -rf /some/path/
mkdir /some/path/

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


2
Але що робити, якщо я хочу лише видалити приховані файли?
CMCDragonkai

@CMCDragonkai, це має бути іншим питанням, але ви можете знайти рішення у відповіді Жиля ( rm ..?* .[!.]*слід це зробити).
evilsoup

15
Якщо не видалити та відтворити каталог, це створює ризик того, що права доступу до файлів після цього будуть неправильними (особливо важливо в серверних середовищах). Хто міг створити папку з тими ж дозволами, що й раніше, автоматично?
Йо Людке

1
@YoLudke Ви абсолютно правильні, у багатьох ситуаціях це не має значення, але видалення папки та відтворення не є семантично рівнозначним випорожненню цієї папки; тому будьте обережні, роблячи це!
Томас

Видалити каталог не завжди можливо. У моєму випадку каталог є докерним томом, і, хоча я можу робити все, що хочу всередині тома, я не можу змінити сам том зсередини контейнера.
dovidweisz

85

*відповідає всім неточним файлам, .[!.]*відповідає всім крапковим файлам, за винятком .файлів, ім’я яких починається з .., і ..?*відповідає всім крапковим файлам, за винятком ... Разом вони відповідають усім файлам, окрім .та ... Якщо будь-який із цих трьох шаблонів нічого не відповідає, він розширюється до себе; rm -fне байдуже до неіснуючих аргументів, тому це не має значення.

rm -rf ..?* .[!.]* *

Ви також можете використовувати find. Це складніше, але має перевагу в роботі, навіть якщо файлів так багато, що макіяж вище може бути розширений за межі довжини командного рядка вашої системи.

find . -name . -o -prune -exec rm -rf -- {} +

Можливо, вам буде зрозуміліше видалити та відтворити каталог. Це має перевагу (або вниз, залежно від випадку) в результаті отримання порожнього каталогу, навіть якщо інша програма одночасно створює файли в вихідному каталозі.


8
Це має бути прийнятою відповіддю, оскільки це перешкоджає обходу батьків та можливому видаленню.
rbellamy

findАльтернатива повертає «успіх» , навіть якщо якийсь - то файл не був успішно видалений; не добре для сценарію.
Франклін Ю

Що стосується вашої другої findкоманди, то на сторінці сторінки пошуку зазначено "Оскільки -delete означає -depth, ви не можете корисно використовувати -prune та -delete разом." - все-таки ти користуєшся -prune -delete?
Doktor J

@DoktorJ Дійсно, тут -pruneнічого не робиться. І коли я читаю назад, я бачу, що я не відповів правильно на питання: я подбав про те, щоб не повторюватись, але питання прямо вимагає рекурсивного видалення. Я виправив свою відповідь.
Жиль

2
@haylem У zsh вам потрібно писати .[^.]*замість того, .[!.]*коли включена підміна історії (що за замовчуванням є випадком інтерактивного, але не в сценаріях), оскільки zsh аналізує !як посилання на історію. Але в zsh вам не знадобиться це в першу чергу, ви можете просто використовувати *(D)для включення точкових файлів (без .або ..) у підстановку підстановок.
Жиль

21

Щойно зрозумів, що це найбільш зручний спосіб у більшості дистрибутивів Linux:

ls -A1 | xargs rm -rf

де

-A= перелічити все, крім . і..

-1 = покладіть кожен елемент в один рядок


4
Мінус, який я бачу, такий: для цього вам потрібно 'CD' в каталог.
кумар

ls -A1 /your/path/ | xargs rm -rfслід подати заяву
godzillante

nope..it не допомагає - Наприклад: ls -A1 ~ / test / | xargs rm -rf ця команда видаляє файли, які я зараз 'cd в' .. не в каталозі ~ / test.
кумар

5
Він не працює, якщо будь-яке ім’я файлів містить пробіли, нові рядки, лапки або зворотні риски.
Стефан Шазелас

1
-1 Через вищезазначений коментар. ↑↑↑↑↑↑↑↑
somethingSomething

15

Або змінити dotglobпараметр своєї оболонки і використовувати *, або використовувати щось подібне find.

find somedir -mindepth 1 -delete

2
Або ви могли просто, rm -rf /some/dirа потім створити на своєму місці новий порожній каталог.
трійка

Найкращий варіант поки що. Дуже безпечно, оскільки ви чітко вказуєте шлях до каталогу.
Янік Жируар

4

Це має працювати так само, як відповідь @Gilles, але більш компактне:

rm -rf {,.[!.],..?}*

або

rm -rf dir/to/files/{,.[!.],..?}*

слід також додати ifвикористання для сценаріїв, щоб бути безпечним:

if [ -d "$DIR" ]; then
    rm -rf ${DIR}/{,.[!.],..?}*
fi

1
Як не дивно, попередній варіант відповіді не міг працювати як псевдонім Ubuntu 16.04 LTS. Однак alias cleandir='rm -rf {,.[!.],..?}*'робить.
Стівен Вентімілья

3

Знайдіть свого друга.

find ! -name '.' ! -name '..' -delete

% find ! -name '.' ! -name '..'
./test
./test4
./test4/.test6
./test3
./.test5
./test2
% find ! -name '.' ! -name '..' -delete    
% find ! -name '.' ! -name '..'     
%             

Якщо ви хочете використовувати рекурсивно шукати щось інше у вашому поточному каталозі ($ PWD), додайте шлях безпосередньо після findкоманди; наприклад, find /path ! -name '.' ! -name '..' -delete. Якщо ви хочете лише зменшити nкількість каталогів, то скористайтеся -maxdepth nопцією відразу після /pathпараметра.

Вищевказана команда була протестована в системі Ubuntu 13.04. Ймовірно, буде працювати в інших сучасних системах Linux.


видалити всі каталоги в поточному каталозі, який ви могли зробитиfind . ! -name '.' ! -name '..' -type d -delete
Енді

2

Який правильний спосіб видалити всі приховані та не приховані файли та папки рекурсивно в цільовому каталозі, не отримуючи попередження / помилку про. і ..?

Якщо припустити , що каталог в питанні ./dir, то

rm -rf ./dir

буде видалено всі файли в ./dir, включаючи приховані файли та каталоги, рекурсивно, включаючи сам ./dirкаталог.

Якщо ви не хочете видалити сам каталог, ви можете просто відтворити його згодом або використовувати

find ./dir -mindepth 1 -delete

або якщо ви findне підтримуєте -delete,

find ./dir -mindepth 1 -depth -exec rm -rf {} ';'

Використання -mindepth 1дозволяє зберігати каталог верхнього рівня ./dir.


це слід позначити як найкращу відповідь
kitingChris

1

Я пропоную вам експериментувати

Turn- ON точок (приховані файли)

  • набір dotglob

    shopt -s dotglob

Turn- OFF точки

  • невдалий dotglob

    shopt -u dotglob

Цей метод спрацював саме так, як я хотів, щоб команда копіювання, у якій були відсутні приховані каталоги.

    shopt -s    dotglob
    cp    -rvn  ./$from/*  ./$too/
    shopt -u    dotglob

Тож я зробив видалення (видалення) і ой ...

    shopt -s    dotglob
    rm -fr ../message_splitter--044a/*
    shopt -u    dotglob

... це теж працює!

Мені здається, що ви, шановний читачу, не можете бачити message_splitterкаталог. Будь-який спосіб має .svnпапку, яку потрібно видалити та скопіювати в Into.

Зі manсторінки ...

dotglob Якщо встановлено, bash включає в себе назви файлів, що починаються з "." в результатах розширення імені шляху.

посилання:


-2

Спробуйте цей код:

Dirlist=``find /some/path/ -type d -name '.[^.]*'`
for HiddenDir in $Dirlist
do
    rm -rf $HiddenDir
done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.