Как удалить все файлы / папки из папки, кроме нескольких папок?
Я пытаюсь написать сценарий сопровождающего для debian
пакет. Предположим, что у меня есть структура каталогов следующим образом:
application/
----application/file1.txt
----application/file2.txt
----application/config
--------application/config/c1.conf
--------application/config/c2.conf
----application/logs
--------application/logs/l1.txt
--------application/logs/l2.txt
----application/src
--------application/src/static/
------------application/src/static/js
------------application/src/static/css
--------application/src/s1.py
--------application/src/s2.py
----application/lib
--------application/src/js/
--------application/src/css/
Теперь я хочу удалить все файлы / папки, кроме config
а также logs
(в этом случае, src
а также lib
папки и file1.txt
а также file2.txt
файлы). мой PWD
в настоящее время является родителем appliaction/
реж (то есть я вижу application
в моем PWD
).
Какую команду я должен использовать (маленький bash script
было бы замечательно)? (Я пробовал с rm -rf
с некоторыми опциями, но по ошибке удалил другие файлы, поэтому я хотел бы узнать правильный ответ, прежде чем пытаться что-либо еще!)
6 ответов
Из того, что я собираю, есть куча других папок, кроме src
потому что в противном случае вы бы просто использовать rm -rf src
,
Если твой PWD
является application
вы находитесь в родительском каталоге config
logs
а также src
, вам просто нужен способ использовать rm -rf
на все файлы / папки, кроме config
а также log
Так почему бы не сделать цикл?
#!/bin/bash
cd "/path/to/application"
for file in * ; do
case "$file" in
config )
echo "file is $file: doing nothing"
;;
logs )
echo "file is $file: doing nothing"
;;
* )
echo "file is $file: removing"
rm -rf "$file"
;;
esac
done
exit 0
Это должно работать:
find ./application -depth -mindepth 1 -type d \
-regextype posix-extended ! -regex ".*\/(config|logs).*" | \
-exec rm -fr {} \;
Или с xargs
если у вас нет имен папок с символами новой строки, вы можете написать:
find ./application -depth -mindepth 1 -type d \
-regextype posix-extended ! -regex ".*\/(config|logs).*" | \
xargs -t -I {} rm -fr {}
Или с xargs
если у вас есть имена папок с символами новой строки, вы можете использовать:
find ./application -depth -mindepth 1 -type d \
-regextype posix-extended ! -regex ".*\/(config|logs).*" -print0 | \
xargs -0 -t -I {} rm -fr {}
find
находит все каталоги ниже./application
исключая те, которые имеют/config
а также/logs
и печатает их, начиная с самого низкогоxargs
запускает удаление каталога
Используя Bash:
for file in applications/*; do
target="${file#*/}"
if [[ $target != config && $target != logs ]]; then
rm -rf "$file"
fi
done
Поскольку вы просто удаляете application/application/src
dir, нет причин использовать find и т.д.. Все, что вам нужно сделать, это:
rm -rf application/application/src
остальной:
application/application/logs/l2.txt
application/application/logs/l1.txt
application/application/config/c1.conf
application/application/config/c2.conf
Нет необходимости в сложном find
Команды, просто используйте оболочку (если вы находитесь в папке приложения):
rm -r !(logs|config)
Это называется "Расширение пути", из man bash
!(pattern-list) Matches anything except one of the given patterns
cd application
find . -type d | egrep -v '(^\./$|^\./log|^\./config)' | while read DIR
do
echo rm -rf $DIR
done
Это использует find, чтобы вывести список всех каталогов, направляет через grep, чтобы исключить те, которые мы хотим сохранить (также исключая "./", который будет PWD), и передает этот фильтрованный список в цикл while, который выполняет удаление. Я добавил туда "эхо", чтобы вы могли проверить, выполняет ли это то, что вам действительно нужно. Если вы счастливы, тогда удалите эхо. Так как возвращаемый список (DIR) будет в древовидном порядке, например, d1, d1/d1a, d1/d1b, а rm -rf d1 удалит нижние папки, вы можете добавить "if [ -d $DIR ]"вокруг рм-рф.