【问题标题】:Delete all files and directories but certain ones using Bash删除所有文件和目录,但使用 Bash 删除某些文件和目录
【发布时间】:2026-02-02 19:00:01
【问题描述】:

我正在编写一个脚本,它需要从一个目录中删除所有内容,除了两个目录 mysql 和 temp。

我试过了:

ls * | grep -v mysql | grep -v temp | xargs rm -rf

但这也保留了所有名称中包含 mysql 的文件,我不需要这些文件。它也不会删除任何其他目录。

有什么想法吗?

【问题讨论】:

    标签: bash file ubuntu directory


    【解决方案1】:

    你可以试试:

    rm -rf !(mysql|init)
    

    这是POSIX defined

     Glob patterns can also contain pattern lists. A pattern list is a sequence
    of one or more patterns separated by either | or &. ... The following list
    describes valid sub-patterns.
    
    ...
    !(pattern-list):
        Matches any string that does not match the specified pattern-list.
    ...
    

    注意:请先花点时间测试一下!要么创建一些测试文件夹,要么只是echo 参数替换,正如@mnagel 适当指出的那样:

    echo !(mysql|init)
    

    Adding useful information: 如果匹配不是active,你可以通过以下方式启用/禁用它:

    shopt extglob                   # shows extglob status
    shopt -s extglob                # enables extglob
    shopt -u extglob                # disables extglob
    

    【讨论】:

    • 就像一个魅力!谢谢! (肯定是在其他地方测试,不想破坏)
    • 如果这回答了您的问题,请将答案标记为已接受。它既可以让其他人知道问题已得到解答,因为这意味着您承认其他人为帮助您所做的努力。要接受答案,请点击投票箭头下方的勾号。
    • 用于测试使用echo,如echo !(mysql|init)
    • > 好的,这在命令行中有效,但在我的脚本中无效。语法错误:“(”意外在脚本中,您需要显式启用扩展通配符。将其放在行上方的任何位置:shopt -s extglob 请参阅*.com/questions/216995/…
    • @Motin 注意到了!我已经添加了你指出的信息。谢谢!
    【解决方案2】:

    这通常是find 的工作。尝试以下命令(如果需要递归删除,请添加 -rf):

    find . -maxdepth 1 \! \( -name mysql -o -name temp \) -exec rm '{}' \;
    

    (也就是说,在. 中查找条目,但在不是[命名为mysql 或命名为tmp] 的子目录中查找条目,并在它们上调用rm。)

    【讨论】:

    • 这也会删除两个文件夹中的文件
    • 不适用于maxdepth 选项。删除-exec rm '{}' \; 以获取匹配文件的列表,其中不包括./ 以下的任何内容。
    • 这也会返回.,所以如果你正在执行rm -Rf,可能会删除比你想要的更多...
    • 添加-mindepth 1 避免删除当前目录。
    【解决方案3】:

    你可以使用find,忽略mysql和temp,然后rm -rf。

    find . ! -iname mysql ! -iname temp -exec rm -rf {} \;
    

    【讨论】:

    • 这也会删除两个文件夹中的文件
    • 要不删除这些文件夹中的所有内容,请使用find . -maxdepth 1 ! -iname mysql ! -iname temp -exec rm -rf {} \;,或者更好的是find . -maxdepth 1 ! -iname mysql ! -iname temp -delete
    • 这又不会删除其他子目录中的任何内容。