220

使用时sudo rm -r,如何删除所有文件,以下文件除外:

textfile.txt
backup.tar.gz
script.php
database.sql
info.txt
4

20 回答 20

229
find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete

如果您不指定-type ffind 还将列出您可能不想要的目录。


或者使用非常有用的组合的更通用的解决方案find | xargs

find [path] -type f -not -name 'EXPR' -print0 | xargs -0 rm --

例如,删除当前目录中所有非 txt 文件:

find . -type f -not -name '*txt' -print0 | xargs -0 rm --

如果应删除的任何文件名中有空格,则需要andprint0组合。-0

于 2010-12-01T14:28:49.703 回答
155
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)

需要在 BASH 中启用 extglob(扩展模式匹配)(如果未启用):

shopt -s extglob
于 2013-03-05T19:38:44.500 回答
41

find . | grep -v "excluded files criteria" | xargs rm

这将列出当前目录中的所有文件,然后列出所有不符合您的条件的文件(注意它匹配的目录名称),然后删除它们。

更新:根据您的编辑,如果您真的想从当前目录中删除除您列出的文件之外的所有内容,可以使用:

mkdir /tmp_backup && mv textfile.txt backup.tar.gz script.php database.sql info.txt /tmp_backup/ && rm -r && mv /tmp_backup/* . && rmdir /tmp_backup

它将创建一个备份目录/tmp_backup(你有 root 权限,对吗?),将列出的文件移动到该目录,递归删除当前目录中的所有内容(你知道你在正确的目录中,对吗?),移动从所有内容返回当前目录/tmp_backup,最后删除/tmp_backup.

我选择将备份目录放在根目录中,因为如果您尝试从根目录递归删除所有内容,您的系统将出现大问题。

当然还有更优雅的方法可以做到这一点,但这个方法非常简单。

于 2010-12-01T14:22:44.750 回答
23

我更喜欢使用子查询列表:

rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`

-v, --invert-match 选择不匹配的行

\|分隔器

于 2017-09-27T01:28:22.587 回答
20

假设具有这些名称的文件存在于目录树中的多个位置,并且您希望保留所有这些文件:

find . -type f ! -regex ".*/\(textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt\)" -delete
于 2010-12-01T15:35:14.620 回答
19

您可以在 Bash 中使用 GLOBIGNORE 环境变量。

假设您要删除除php和sql之外的所有文件,那么您可以执行以下操作 -

export GLOBIGNORE=*.php:*.sql
rm *
export GLOBIGNORE=

像这样设置 GLOBIGNORE 会忽略通配符中的 php 和 sql,例如“ls *”或“rm *”。因此,在设置变量后使用“rm *”只会删除 txt 和 tar.gz 文件。

于 2012-05-04T12:37:26.757 回答
9

由于没有人提到它:

  • 将不想删除的文件复制到安全的地方
  • 删除所有文件
  • 将复制的文件移回原位
于 2012-12-21T21:55:25.697 回答
6

您可以为此编写一个 for 循环... %)

for x in *
do
        if [ "$x" != "exclude_criteria" ]
        then
                rm -f $x;
        fi
done;
于 2010-12-01T14:29:58.727 回答
6

OP 有点晚了,但希望对后来通过谷歌到达这里的任何人都有用......

我发现@awi 的答案和@Jamie Bullock 对-delete 的评论非常有用。一个简单的实用程序,因此您可以在不同的目录中执行此操作,每次忽略不同的文件名/类型,只需最少的输入:

rm_except (或任何你想命名的)

#!/bin/bash

ignore=""

for fignore in "$@"; do
  ignore=${ignore}"-not -name ${fignore} "
done

find . -type f $ignore -delete

例如删除除文本文件和 foo.bar 之外的所有内容:

rm_except *.txt foo.bar 

类似于@mishunika,但没有 if 子句。

于 2014-04-10T18:08:47.060 回答
5

如果您使用zsh的是我强烈推荐的。

rm -rf ^file/folder pattern to avoid

extended_glob

setopt extended_glob
rm -- ^*.txt
rm -- ^*.(sql|txt)
于 2016-04-27T06:23:09.670 回答
4

只是:

rm $(ls -I "*.txt" ) #Deletes file type except *.txt

或者:

rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf
于 2017-08-11T06:35:33.207 回答
4

尝试使用:

rm -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public)

但是带空格的名称(一如既往)很难。也尝试用Virtualbox\ VMs引号代替。它总是删除那个目录 ( Virtualbox VMs)。

于 2015-12-08T17:14:31.173 回答
2

使文件不可变。甚至不允许 root 删除它们。

chattr +i textfile.txt backup.tar.gz script.php database.sql info.txt
rm *

所有其他文件已被删除。
最终,您可以将它们重置为可变的。

chattr -i *
于 2018-04-11T12:48:38.080 回答
1

我相信你可以使用

rm -v !(filename)

除了文件名,所有其他文件都将在目录中删除,并确保您正在使用它

于 2020-08-20T18:52:06.453 回答
0

这类似于@siwei-shen 的评论,但您需要该-o标志来执行多种模式。该-o标志代表“或”

find . -type f -not -name '*ignore1' -o -not -name '*ignore2' | xargs rm

于 2015-02-23T23:20:55.847 回答
0

您可以使用两个命令序列来执行此操作。首先使用您不想排除的文件的名称定义一个数组:

files=( backup.tar.gz script.php database.sql info.txt )

之后,遍历您要排除的目录中的所有文件,检查文件名是否在您不想排除的数组中;如果不是,则删除该文件。

for file in *; do
  if [[ ! " ${files[@]} " ~= "$file"  ]];then
    rm "$file"
  fi
done
于 2017-01-27T19:34:58.797 回答
0

我正在寻找的答案是运行脚本,但我想避免删除脚本本身。因此,如果有人正在寻找类似的答案,请执行以下操作。

创建一个 .sh 文件并编写以下代码:

    cp my_run_build.sh ../../ 
    rm -rf * cp  
    ../../my_run_build.sh . 
    /*amend rest of the script*/
于 2022-02-24T22:05:17.993 回答
-1

由于还没有人提到这一点,在一个特殊情况下:

OLD_FILES=`echo *`
... create new files ...
rm -r $OLD_FILES

(或只是rm $OLD_FILES

或者

OLD_FILES=`ls *`
... create new files ...
rm -r $OLD_FILES

shopt -s nullglob如果某些文件可能存在或不存在,您可能需要使用:

SET_OLD_NULLGLOB=`shopt -p nullglob`
shopt -s nullglob
FILES=`echo *.sh *.bash`
$SET_OLD_NULLGLOB

没有 nullglob,echo *.sh *.bash可能会给你“a.sh b.sh *.bash”。

(说了这么多,我自己更喜欢这个答案,即使它在 OSX 中不起作用)

于 2018-04-11T14:18:20.737 回答
-3

而不是直接命令,请将所需文件移动到当前目录之外的临时目录。rm *然后使用或删除所有文件rm -r *

然后将所需文件移动到当前目录。

于 2013-01-01T04:33:57.623 回答
-3

删除所有排除文件名:

ls -d /path/to/your/files/* |grep -v file.name|xargs rm -rf
于 2018-09-08T12:54:15.000 回答