Удалите все файлы в каталоге (не трогайте ни папки, ни что-нибудь в них)
Я хотел бы знать, может ли rm
удалить все файлы в каталоге (но не вложенные папки или файлы внутри подпапок)?
Я знаю, что некоторые люди используют:
rm -f /direcname/*.*
но это предполагает, что имя файла имеет расширение, которое не все (я хочу, чтобы все файлы - с или без расширения были удалены).
Ответы
Ответ 1
Хотя find позволяет удалять файлы с помощью -exec rm {} \;
, вы можете использовать
find /direcname -maxdepth 1 -type f -delete
и быстрее. Использование -delete подразумевает параметр -depth, что означает содержимое каталога процесса перед каталогом.
Ответ 2
find /direcname -maxdepth 1 -type f -exec rm {} \;
Пояснение:
-
find
выполняет поиск файлов и каталогов в /direcname
-
-maxdepth
ограничивает его поиском файлов и каталогов, которые являются прямыми дочерними элементами /direcname
-
-type f
ограничивает поиск файлов
-
-exec rm {} \;
запускает команду rm {}
для каждого файла (после замены пути к файлу вместо {}
).
Ответ 3
Я хотел бы знать, может ли rm удалить все файлы в каталоге (но не вложенные папки или файлы в подпапках)?
Это легко:
$ rm folder/*
Без -r
команда rm
не будет касаться подкаталогов или файлов, которые они содержат. Это приведет только к удалению файлов в folder
, а не подкаталогах или их файлах.
Вы увидите ошибки, сообщающие вам, что папка /foo - это каталог, который нельзя удалить, но на самом деле это нормально с вами. Если вы хотите удалить эти сообщения, просто перенаправьте STDERR:
$ rm folder/* 2> /dev/null
Кстати, статус выхода команды rm
может не быть нулевым, поэтому вы не можете проверить rm
на наличие ошибок. Если это важно, вам придется зацикливаться:
$ for file in *
> do
> [[ -f $file ]] && rm $file
> [[ $? -ne 0 ]] && echo "Error in removing file '$file'"
> done
Это должно работать в BASH, даже если имена файлов содержат пробелы.
Ответ 4
Вы можете использовать
find /direcname -maxdepth 1 -type f -exec rm -f {} \;
Ответ 5
Решение оболочки (без нестандартного find -maxdepth) будет
for file in .* *; do
test -f "$file" && rm "$file"
done
Ответ 6
Некоторые оболочки, в частности zsh и, возможно, bash версия 4 (но не версия 3), имеют синтаксис для этого.
С помощью zsh вы можете просто ввести
rm /dir/path/*(.)
и если вы хотите удалить любой файл, чье имя начинается с foo, рекурсивно в подкаталогах, вы можете сделать
rm /dir/path/**/foo*(.)
функция двойной звезды (с улучшенным интерактивным завершением IMHO), на мой взгляд, достаточно, чтобы переключиться на zsh для интерактивных оболочек. YMMV
Точка в суффиксе в скобках указывает, что вы хотите, чтобы только файлы (а не символические ссылки или каталоги) расширялись оболочкой zsh.
Ответ 7
Unix не DOS. В имени файла нет специального поля расширения. Любые символы после точки являются лишь частью имени и называются суффиксом. Может быть более одного суффикса, например .tar.gz
. Символ оболочки gl > *
соответствует символу .
; он не обращает внимания на суффиксы. Таким образом, MS-DOS *.*
является просто *
В Unix.
Почти. *
не соответствует файлам, начинающимся с .
. Объекты, названные с ведущей точкой, являются, по соглашению, "скрытыми". Они не отображаются в ls
, если вы не укажете -a
.
(Это означает, что записи каталога .
и ..
для "self" и "parent" считаются скрытыми.)
Чтобы также найти скрытые записи, используйте .*
Команда rm
не удаляет каталоги (если не рекурсивно работать с -r
).
Попробуйте rm <directory>
и посмотрите. Даже если каталог пуст, он откажется.
Таким образом, фактически вы удаляете все (не скрытые) файлы, трубы, устройства, сокеты и символические ссылки из каталога (но оставляете только подкаталоги):
rm /path/to/directory/*
также удалить скрытые, которые начинаются с .
:
rm /path/to/directory/{*,.*}
Этот синтаксис является расширением скобки. Расширение скобки не соответствует шаблону; это просто короткая рука для генерации нескольких аргументов, в данном случае:
rm /path/to/directory/* /path/to/directory/.*
это разложение происходит сначала, а затем происходит сглаживание, чтобы сгенерировать имена, которые нужно удалить.
Обратите внимание, что различные решения, размещенные здесь, имеют различные проблемы:
find /path/to/directory -type f -delete
# -delete is not Unix standard; GNU find extension
# without -maxdepth 1 this will recurse over all files
# -maxdepth is also a GNU extension
# -type f finds only files; so this neglects to delete symlinks, fifos, etc.
У решений поиска GNU есть то преимущество, что они работают, даже если количество удаляемых записей каталога огромно: слишком большой, чтобы передать один вызов rm
. Другим преимуществом является то, что встроенный -delete
не имеет проблем с передачей смежных имен пути внешней команде.
Переносимым решением проблемы слишком большого количества записей каталога является список записей с ls
и pipe на xargs
:
( cd /path/to/directory ; ls -a | xargs rm -- )
Скобки означают "выполнять эти команды в подпроцессе"; таким образом, эффект cd
забывается, что полезно при написании сценариев. ls -a
содержит скрытые файлы.
Теперь мы включаем --
после rm
, что означает "это последний вариант, а все остальное - аргумент без опции". Это защищает нас от записей каталога, имена которых неотличимы от параметров. Что делать, если файл называется -rf
и заканчивается первым аргументом? Затем у вас есть rm -rf ...
, который сдует подкаталоги.
Ответ 8
Простая оболочка оболочки:
% tree
.
├── 1
├── 2
├── 3
├── 4
├── 5
└── bar
├── a
├── b
├── c
├── d
└── e
1 directory, 10 files
% rm -f *
rm: cannot remove ‘./bar’: Is a directory
% tree .
.
└── bar
├── a
├── b
├── c
├── d
└── e
1 directory, 5 files
как и в ответе Йенса, вам может потребоваться добавить второй rm -f .*
, но это только в том случае, если вы ожидаете скрытых файлов в своем основном каталоге. Нет необходимости проверять тип (test -f
), поскольку параметр rm -f
не удаляет каталоги. Это, однако, также удалит "специальные" файлы, такие как символические ссылки и блокирующие устройства.
Ответ 9
Самый простой способ сделать это - использовать:
rm *
Чтобы удалить каталоги, вы должны указать опцию -r
rm -r
поэтому ваши каталоги и все, что содержится в них, не будут удалены с помощью
rm *
на странице man для rm, его целью является удаление файлов, поэтому это работает