Как удалить все файлы / папки из папки, кроме нескольких папок?

Я пытаюсь написать сценарий сопровождающего для 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вы находитесь в родительском каталоге configlogs а также 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 ]"вокруг рм-рф.

Другие вопросы по тегам