如何删除文件夹中除了几个特定文件夹外的所有文件/文件夹?

6

我正在尝试为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”文件)。 我的当前PWDappliaction/ dir的父级(即,我可以在我的PWD中看到application)。
请问我应该使用什么命令(一个小的bash脚本会很好)? (我尝试了一些选项的rm -rf,但错误地删除了其他文件,因此在尝试其他任何操作之前,我想知道正确的答案!)

你尝试了哪些选项?因为你可以使用普通的 rm 命令来完成这个任务(请参考我的回答)。 - Bernhard
6个回答

1
据我所知,除了src文件夹之外,还有许多其他文件夹,否则你就只需要使用rm -rf src命令。
如果您的PWDapplication,即您在configlogssrc的父目录中,您只需要找到一种方法来使用rm -rf删除除configlog之外的所有文件/文件夹,那为什么不使用for循环呢?
    #!/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

这不会删除文件。 - Bernhard
请检查编辑下的原始帖子。它明确提到了文件夹。在我回答之后,“文件/文件夹”被添加到问题中。无论如何,要删除文件,只需从上面删除if语句,并且只要没有名为config或logs的文件且没有任何扩展名,此脚本就会按预期工作。 - Brian Albert Monroe
啊,我讨厌人们如此大幅度地改变他们的问题。但也许去掉if语句以保持一致性是个好主意? - Bernhard
确定,更改已完成。我是这个论坛的新手,不太清楚如果在正确答案被提供后修改原始帖子时应该遵守什么礼仪。如果你没有指出问题已经更新,我可能永远都不会检查这个帖子了。 - Brian Albert Monroe
嗯,通常情况下这样做并不受欢迎,但在这种情况下它并不会造成太大的伤害。我点赞了,因为这个解决方案应该是可行的,虽然我认为我的更好 ;) - Bernhard

1
这必须工作:
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 命令运行并删除该目录。

0

既然你只是删除了application/application/src目录,就没必要使用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

0
cd application
find . -type d | egrep -v '(^\./$|^\./log|^\./config)' | while read DIR
do
   echo rm -rf $DIR
done

这里使用find列出所有目录,通过管道传递给grep来排除我们想保留的目录(也要排除"./",因为它是PWD),然后将过滤后的列表传递给while循环进行删除。我在其中加入了"echo",以便您测试是否实现了您想要的功能。如果您满意,则可以删除echo。由于返回的列表(DIR)是树形顺序,例如d1、d1/d1a、d1/d1b,而rm -rf d1会删除较低的文件夹,因此您可能需要在rm -rf周围添加一个"if [ -d $DIR ]"。


糟糕,太晚了,我的答案和skwilsp的一样。他在我写答案的时候已经回答了。我认为他的更简洁。 - TenG
在bash中永远不要使用大写变量,将其保留为系统变量的反转形式。 - Bernhard

0

使用Bash:

for file in applications/*; do
    target="${file#*/}"
    if [[ $target != config && $target != logs ]]; then
        rm -rf "$file"
    fi
done

0

不需要复杂的find命令,只需使用shell(假设您在应用程序文件夹中):

rm -r !(logs|config)

这被称为“路径名扩展”,来自于man bash
         !(pattern-list)
                Matches anything except one of the given patterns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接