rm -rf все файлы и все скрытые файлы без. & .. ошибка

83

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

rm -rf /some/path/.* удаляет все скрытые файлы в этом каталоге (но не в подкаталогах), а также выдает следующую ошибку / предупреждение:

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

Как правильно рекурсивно удалять все скрытые и не скрытые файлы и папки в целевом каталоге, не получая предупреждение / ошибка об .и ..?

Джейк Уилсон
источник

Ответы:

40

Вы всегда можете отправить сообщение об ошибке /dev/null

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

Вы также можете просто

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

... тогда вам не придется беспокоиться о скрытых файлах.

evilsoup
источник
2
Но что, если я хочу удалить только скрытые файлы?
CMCDragonkai
@CMCDragonkai, это должен быть другой вопрос, но вы можете найти решение в ответе Жиля ( rm ..?* .[!.]*должен это сделать).
evilsoup
15
Отсутствие удаления и воссоздания каталога создает риск того, что права доступа к файлам будут неправильными (особенно важно в серверных средах). Кто может автоматически создать папку с теми же правами доступа, что и раньше?
Йо Людке,
1
@YoLudke Вы абсолютно правы, во многих ситуациях это не имеет значения, но удаление папки и ее повторное создание семантически не эквивалентно очистке этой папки; так что будьте осторожны!
Томас
Удаление каталога не всегда возможно. В моем случае каталог является томом докера, и хотя я могу делать все, что захочу внутри тома, я не могу изменить сам том изнутри контейнера.
dovidweisz
84

*соответствует всем не точечным файлам, .[!.]*соответствует всем точечным файлам, за исключением .файлов, имя которых начинается с .., и ..?*соответствует всем точечным файлам, кроме ... Вместе они соответствуют всем файлам, кроме .и ... Если какой-либо из этих трех шаблонов ничего не соответствует, он расширяется сам по себе; rm -fне заботится о несуществующих аргументах, так что это не имеет значения.

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

Вы также можете использовать find. Это сложнее, но имеет преимущество работы даже в том случае, если существует так много файлов, что указанные выше символы подстановки выходят за пределы длины командной строки вашей системы.

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

Возможно, вам будет проще удалить и заново создать каталог. Это имеет преимущество (или недостаток, в зависимости от обстоятельств) в результате создания пустого каталога, даже если другая программа одновременно создает файлы в исходном каталоге.

жилль
источник
8
Это должен быть принятый ответ, так как он предотвращает родительский обход и возможное удаление.
rbellamy
findАльтернатива возвращает «успех» , даже если какой - то файл не был успешно удален; не подходит для сценария.
Франклин Ю
Что касается вашей второй findкоманды, на странице поиска указано состояние «Поскольку -delete подразумевает -depth, вы не можете использовать -prune и -delete вместе». - вы еще используете -prune -delete?
Доктор Дж
@DoktorJ Действительно, здесь -pruneничего не делается. И после прочтения я вижу, что не правильно ответил на вопрос: я позаботился о том, чтобы не повторять, но вопрос явно требует рекурсивного удаления. Я исправил свой ответ.
Жиль
2
@haylem В zsh вам нужно писать .[^.]*вместо .[!.]*включения подстановки истории (что по умолчанию происходит в интерактивном режиме, но не в сценариях), потому что zsh анализирует !как ссылку на историю. Но в zsh это вам не нужно, во-первых, вы можете просто использовать, *(D)чтобы включить точечные файлы (без .или ..) в совпадении с подстановочными знаками.
Жиль
21

Просто понял, что это самый удобный способ в большинстве дистрибутивов Linux:

ls -A1 | xargs rm -rf

где

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

-1 = положить каждый элемент в одну строку

godzillante
источник
4
Недостатком, который я вижу, является то, что вам нужно «cd» в каталог, чтобы сделать это.
Кумар
ls -A1 /your/path/ | xargs rm -rfследует подать заявку
Годзилланте
Нет .. это не помогает - Например: ls -A1 ~ / test / | xargs rm -rf эта команда удаляет файлы, в которые я сейчас вхожу "cd into" .. нет в каталоге ~ / test.
Кумар
5
Это не работает, если любое из имен файлов содержит пробелы, символы новой строки, кавычки или обратную косую черту.
Стефан
1
-1 Из-за вышеприведенного комментария. ↑↑↑↑↑↑↑↑
что-то что-то
15

Либо измените dotglobопцию вашей оболочки и используйте *, либо используйте что-то подобное find.

find somedir -mindepth 1 -delete
Игнасио Васкес-Абрамс
источник
2
Или вы можете просто rm -rf /some/dirи затем создать новый пустой каталог на его месте.
tripleee
Лучший вариант пока. Очень безопасно, так как вы явно указываете путь к каталогу.
Яник Жируард
4

Это должно работать так же, как ответ @Gilles, но более компактно:

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

или же

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

Следует также добавить ifдля использования в сценариях просто для безопасности:

if [ -d "$DIR" ]; then
    rm -rf ${DIR}/{,.[!.],..?}*
fi
Павел Прагак
источник
1
Как ни странно, в качестве псевдонима bash на 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.

laebshade
источник
удалить все каталоги в текущем каталоге, которые вы могли бы сделать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папка, которую нужно удалить и скопировать в.

Со manстраницы ...

dotglob Если установлено, bash включает имена файлов, начинающиеся с `. ' в результатах расширения пути.

Рекомендации:

будем
источник
-2

Попробуйте этот код:

Dirlist=``find /some/path/ -type d -name '.[^.]*'`
for HiddenDir in $Dirlist
do
    rm -rf $HiddenDir
done
СИЗ
источник