Как удалить все файлы и подкаталоги в каталоге БЕЗ удаления каталога в bash?


53

Есть ли команда удалить все файлы и подкаталоги в каталоге БЕЗ удаления каталога?

Например, если у меня есть каталог "dontDeleteMe" с подкаталогами "1", "2", "3" и в каждом подкаталоге есть несколько изображений, как я могу удалить подкаталоги "1", "2" и "3" и все файлы в них, не удаляя родительский каталог "dontDeleteMe"?

Ответы:


66

Чтобы удалить все в каталоге, не удаляя каталог, введите:

rm -rfv dontDeleteMe/*

Обратите внимание, /*часть очень важна. Если вы поставите пробел перед *, он удалит все ваши файлы в вашем текущем каталоге.

Кроме того , будьте очень осторожны , играя с rm, -rи *все в одной команде. Они могут быть катастрофической комбинацией.

Обновление: Хорошо, я понял, что если у вас есть скрытые / точечные файлы [имена файлов с точками в начале, ex .hidden], то это оставит эти файлы без изменений.

На самом деле, самое простое решение исходного вопроса : rm -rfv dontDeleteMe && mkdir dontDeleteMe

Еще один будет использовать find«s -execварианта или трубу , xargs(ниже):

find dontDeleteMe/* -print0 | xargs -0 rm -rv


Можете ли вы привести пример использования xargs? Что такое XARGS?
Justingrif

@justingrif: find dontDeleteMe/* -print0 | xargs -0 rm -rv я считаю, что в большинстве случаев это будет работать, независимо от пробелов, а что нет. Но перейдите /tmp/и создайте тестовый каталог и попробуйте его. :)
Мэтт

О, и из man- страницы
Matt

5
Повторное создание каталога не означает удаление его содержимого. например, различия в правах доступа к каталогу umask, различия между владельцами и т. д. Ответ enzotib решит проблемы с вашим исходным синтаксисом

3
Это не хороший ответ. Использование * опасно и не будет работать с точечными файлами без «dotglob» (см. Ниже). rm -rf dontDeleteMe && mkdir dontDeleteMeне гарантирует повторное создание каталога с теми же разрешениями / владельцем (-ями). Вместо этого используйте один из find dontDeleteMe/ -mindepth 1 -deleteвариантов ниже.
Нильс Тёдтман

27

Единственная причина rm -r ./*не всегда работает, потому что вы можете иметь скрытые файлы и / или папки, которые не соответствуют *.

Для этого bashпредоставьте возможность *сопоставлять все, даже скрытые объекты:

cd dont-delete-me
shopt -s dotglob
rm -r ./*

Может быть полезно сбросить dotglobего в состояние по умолчанию (unset), если вы продолжаете использовать оболочку, в которой вы выполняли вышеуказанные команды:

shopt -u dotglob 

Это также может не работать, когда у вас есть большое количество файлов
S ..

23

Откройте терминал ( Ctrl+ Alt+ T) и введите:

find somedir -mindepth 1 -delete

Это будет соответствовать всем файлам и каталогам внутри somedirи его дочерним somedirэлементам -mindepth 1, включая «скрытые» файлы точек, но исключая себя из-за -deleteних.


Добро пожаловать в AskUbuntu! Хотя ваш ответ потенциально может помочь оригинальному постеру, недостаток информации, объясняющей, что это может сделать, чтобы помочь ему / ей, делает ваш ответ неполным.
Ойибо

3
Не хватает объяснения, но все же лучший ответ. Также работает в OSX (кроме способа открытия Терминала, конечно).
noamtm

6
find /dontDeleteMe/ -xdev -depth -mindepth 1 -exec rm -Rf {} \;

Используйте xdevопцию для удаления файлов только в пределах границ устройства.


GNU найти имеет -delete. Это подразумевает -depthи легче запомнить, чем-depth -exec rm -Rf {} \;
Nils Toedtmann

4

Чтобы удалить (в терминале) все файлы и подкаталоги, кроме базового каталога с именем "dontdelete":

rm -rf dontdelete/*

Это не удаляет скрытые файлы, поэтому «все файлы» могут быть слишком смелыми.
Стефан ван ден Аккер

4

Вы можете использовать findс -deleteфлагом:

find dontDeleteMe/* -delete

Это /*важно, так как он говорит findискать только внутри папки с именем "dontDeleteMe".

Также убедитесь, что -deleteфлаг находится в конце findкоманды.


1
Это решение не удаляет скрытые файлы, если вы не включите dotglob. В противном случае использование -mindepth 1опции флага кажется единственным способом заставить его работать.
Стефан ван ден Аккер

3
rm -rf  directory/{.*,/*}

Что говорит:

Удалить все файлы, начиная с. в "каталоге" и всех других файлах тоже.

Хотя, как любезно отметил Нефтас, это решение небезопасно!

Более безопасное решение:

 rm -rf directory/!(.|..)

Эта команда потенциально может быть опасной, так как вы также включаете .и ..каталоги. Этого можно избежать, изменив {.*}на {.??*}, но тогда вы не удалите скрытые файлы только с одним символом, например .a.
Стефан ван ден Аккер

что по этому поводу? rm -rf directory /! (. | ..)
Тебе

Это выглядит намного лучшим решением, чем я придумал. Могу ли я предложить вам отредактировать свой ответ?
Стефан ван ден Аккер

предложение принято)
Tebe

1

Я не уверен, почему это так сложно, помогите мне, если я ошибаюсь

cd DoNotDeleteDir #<- this is just to make sure we are inside
find . | xargs rm -rf

это оно


У этого есть небольшой недостаток в попытке удалить текущий каталог, что, конечно же, не работает, потому что он все еще используется в качестве рабочего каталога вызывающей оболочки.
Дэвид Фёрстер,

1

Есть еще более простой ответ:

  1. cd dontDeleteMe

  2. rm -rf *

Время лекций по базовому системному администрированию. Обязательно обращайте внимание на то, где вы находитесь, когда используете такие развернутые команды.

Я не могу сказать этого достаточно. Я должен был восстановить коробку, потому что кто-то не обращал внимания и печатал в rm -rf *то время как в /.

* nix предполагает, что если вы являетесь пользователем root или вы используете права root, вы знаете, что делаете. Поэтому убедитесь, что вы знаете, что делаете, прежде чем сделать это.

Альтернатива, которая гарантирует, что ваша команда 'cd' работает до того, как вы выполните команду 'rm', заключается в использовании

cd dontDeleteMe && rm -rf *

6
Это опасное предложение. То, что вы хотите: cd dontDeleteMe && rm -rf *
Изката

@Izkata Или перед выполнением команды rm убедитесь, что операция cd прошла успешно.
Элия ​​Каган

1
@EliahKagan Это именно то, что делает мой фрагмент кода ...
Izkata

На самом деле это не более или менее опасно, чем вы предлагаете. Все & & делает, чтобы соединить две команды вместе, чтобы они выполнялись одновременно. Во всяком случае, мой метод на самом деле БЕЗОПАСЕН, так как вы должны остановиться и .look, прежде чем выполнить rm -rf *. Пауза для двойной проверки всегда лучше.
user30619

5
@ user30619 &&Оператор не просто объединяет команды; это требует, чтобы каждая команда была успешной, прежде чем будет выполнена следующая. Если cdкоманда не выполнена по какой-либо причине (каталог не существует, привилегии и т. Д.), То rmкоманда не будет выполнена. Я бы назвал это безопаснее.
ean5533

0
  1. Самая простая вещь для меня - эксперт по Windows, но новичок в Ubuntu
  2. Нажмите значок «Файлы» на панели запуска.
  3. Перейдите в каталог, где находятся файлы и папки, которые вы хотите удалить
  4. Щелкните правой кнопкой мыши в пустой области окна рядом с файлами и нажмите «Открыть в терминале» - оставьте окно «Файлы» открытым
  5. Откроется окно терминала, которое будет «установлено» в папку, которую вы нашли
  6. Вы можете набрать «dir» (игнорировать кавычки, когда я говорю «type») и нажать Enter для терминала, чтобы показать список файлов и папок - просто чтобы доказать, что вы «в» нужной папке
  7. введите "rm -rf *" и нажмите ввод
  8. в зависимости от размера папок / файлов для удаления система сделает паузу
  9. Когда появится запрос терминала, в открывшемся окне «Файлы» появится сообщение «Папка пуста»
  10. У меня был успех с этим методом, и он дал мне комфорт видеть файлы / папку как в окне «Файлы», так и в результате команды Dir в окне терминала
  11. Меня также порадовало, что в окне «Файлы» отображается пустая папка - тем более, что я гонялся за этими файлами в поисках папки с мусором, в которой они находились.
  12. Спасибо всем, кто прислал ответы - это было очень информативно

Это кажется довольно запутанным - тем более, что ты rm -rf *все равно будешь бегать .
Дэвид Фёрстер

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.