На терминале Mac OS X, как мы можем рекурсивно удалить все файлы и папки, включая скрытые, кроме одного каталога?
Спасибо.
ВНИМАНИЕ: запуск любой команды для рекурсивного удаления файлов опасен. Всегда, всегда проверяйте, прежде чем вслепую запускать такие опасные команды, и никогда не запускайте их как пользователь root (или с sudo и т.д.), Никогда .
Это относительно легко сделать с небольшим количеством bash, вы можете даже сделать это аргументом, который вы передаете, если вы собираетесь делать это много. Но, на этот раз, попробуйте что-то вроде моего простого теста ниже.
Сначала я создам несколько папок для тестирования:
cd test; mkdir -p one two three four five six .hidden
Затем я создам скрипт bash (в данном случае rm.bash) со следующим содержимым:
for i in `ls -A`
do
if [ ! "${i}" == 'three' ] && [ ! "${i}" == $0 ]; then
echo "would delete ${i}"
else
echo "not deleting ${i}"
fi
done
Для объяснения: ls -A
распечатает все файлы, кроме текущей папки и родительского файла (.
И ..
). Мы используем этот список с циклом for
для перебора всего содержимого. Я решил (произвольно), что единственная папка, которую мы оставим, это "три" и что я не хочу удалять сам скрипт rm.bash
.
Следовательно, условие if
будет истинным только в том случае, если рассматриваемый файл / папка не назван ни three
ни rm.bash
($0
означает, что это работает независимо от того, как вы называете файл).
Вместо того, чтобы запускать это немедленно с помощью команды rm -rf ${i}
(что опасно), я вместо этого использовал пару команд echo
чтобы показать, что будет удалено, а что нет.
Вот мой пример вывода:
would delete five
would delete four
would delete one
not deleting rm.bash
would delete six
not deleting three
would delete two
После того, как вы убедились, что скрипт выполняет правильные действия, а не удаляет вещи, которые он не должен и т.д., Вы можете изменить код так:
for i in `ls -A`
do
if [ ! "${i}" == 'three' ] && [ ! "${i}" == $0 ]; then
rm -rf ${i}
fi
done
Альтернатива. Те же предостережения, что и в ответе @Adam C; не запускайте это без тестирования.
Некоторые демонстрационные данные:
$ mkdir testing; cd testing
$ mkdir one two three four "fi ve"
$ touch one/one.txt two/two.txt three four/keep.txt fi\ ve/.hidden
Имитация удаления всех, кроме четырех /
$ find . -mindepth 1 -path ./four -prune -o -exec echo would remove "{}" +
Выход:
would remove ./fi ve ./fi ve/.hidden ./two ./two/two.txt ./one ./one/one.txt ./three
Заметки:
-mindepth 1 prevents including /.
Prune removes path four/ from processing, or...
-o means "or" (either prune the left, or exec on the right)
High speed / low resource use:
find will stop processing a tree once pruned (no wasted operations)
One xargs-style list is built (with +), removal happens in one command.
To process one at a time, replace + with \;
Spaces are handled correctly within " "
-delete is shorter but may not operate on directories
find won't follow symlinks by default