使用时sudo rm -r
,如何删除所有文件,以下文件除外:
textfile.txt
backup.tar.gz
script.php
database.sql
info.txt
find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete
如果您不指定-type f
find 还将列出您可能不想要的目录。
或者使用非常有用的组合的更通用的解决方案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
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)
需要在 BASH 中启用 extglob(扩展模式匹配)(如果未启用):
shopt -s extglob
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
.
我选择将备份目录放在根目录中,因为如果您尝试从根目录递归删除所有内容,您的系统将出现大问题。
当然还有更优雅的方法可以做到这一点,但这个方法非常简单。
我更喜欢使用子查询列表:
rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`
-v, --invert-match 选择不匹配的行
\|
分隔器
假设具有这些名称的文件存在于目录树中的多个位置,并且您希望保留所有这些文件:
find . -type f ! -regex ".*/\(textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt\)" -delete
您可以在 Bash 中使用 GLOBIGNORE 环境变量。
假设您要删除除php和sql之外的所有文件,那么您可以执行以下操作 -
export GLOBIGNORE=*.php:*.sql
rm *
export GLOBIGNORE=
像这样设置 GLOBIGNORE 会忽略通配符中的 php 和 sql,例如“ls *”或“rm *”。因此,在设置变量后使用“rm *”只会删除 txt 和 tar.gz 文件。
由于没有人提到它:
您可以为此编写一个 for 循环... %)
for x in *
do
if [ "$x" != "exclude_criteria" ]
then
rm -f $x;
fi
done;
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 子句。
如果您使用zsh
的是我强烈推荐的。
rm -rf ^file/folder pattern to avoid
和extended_glob
setopt extended_glob
rm -- ^*.txt
rm -- ^*.(sql|txt)
只是:
rm $(ls -I "*.txt" ) #Deletes file type except *.txt
或者:
rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf
尝试使用:
rm -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public)
但是带空格的名称(一如既往)很难。也尝试用Virtualbox\ VMs
引号代替。它总是删除那个目录 ( Virtualbox VMs
)。
使文件不可变。甚至不允许 root 删除它们。
chattr +i textfile.txt backup.tar.gz script.php database.sql info.txt
rm *
所有其他文件已被删除。
最终,您可以将它们重置为可变的。
chattr -i *
我相信你可以使用
rm -v !(filename)
除了文件名,所有其他文件都将在目录中删除,并确保您正在使用它
这类似于@siwei-shen 的评论,但您需要该-o
标志来执行多种模式。该-o
标志代表“或”
find . -type f -not -name '*ignore1' -o -not -name '*ignore2' | xargs rm
您可以使用两个命令序列来执行此操作。首先使用您不想排除的文件的名称定义一个数组:
files=( backup.tar.gz script.php database.sql info.txt )
之后,遍历您要排除的目录中的所有文件,检查文件名是否在您不想排除的数组中;如果不是,则删除该文件。
for file in *; do
if [[ ! " ${files[@]} " ~= "$file" ]];then
rm "$file"
fi
done
我正在寻找的答案是运行脚本,但我想避免删除脚本本身。因此,如果有人正在寻找类似的答案,请执行以下操作。
创建一个 .sh 文件并编写以下代码:
cp my_run_build.sh ../../
rm -rf * cp
../../my_run_build.sh .
/*amend rest of the script*/
由于还没有人提到这一点,在一个特殊情况下:
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 中不起作用)
而不是直接命令,请将所需文件移动到当前目录之外的临时目录。rm *
然后使用或删除所有文件rm -r *
。
然后将所需文件移动到当前目录。
删除所有排除文件名:
ls -d /path/to/your/files/* |grep -v file.name|xargs rm -rf