使用时sudo rm -r
,如何删除所有文件,但以下情况除外:
textfile.txt
backup.tar.gz
script.php
database.sql
info.txt
rm -r
暗示- 删除其他所有内容,包括子目录 -即使它们包含具有指定名称的文件;或:(b)遍历目标目录的整个子树,并在每个目录中删除所有文件(列出名称除外)。
使用时sudo rm -r
,如何删除所有文件,但以下情况除外:
textfile.txt
backup.tar.gz
script.php
database.sql
info.txt
rm -r
暗示- 删除其他所有内容,包括子目录 -即使它们包含具有指定名称的文件;或:(b)遍历目标目录的整个子树,并在每个目录中删除所有文件(列出名称除外)。
Answers:
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 --
该print0
和-0
是否有任何应该被删除的文件名的空间需要组合。
find . -type f -not -name '*ignore1' -not -name '*ignore2' | xargs rm
-print0 | xargs -0 rm --
您可以-delete
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)
需要在BASH中启用extglob(扩展模式匹配)(如果未启用):
shopt -s extglob
shopt -s extglob; rm -rf !(README|LICENSE)
。为什么知道吗?
find
了该-delete
选项。
bash
被使用,例如dash
,在extglob
不支持。但是,在交互式 bash
外壳程序中,该命令也将无法按所述方式运行,尽管原因有所不同。简而言之:shopt -s extglob
由ITSELF 执行;一旦成功启用(用验证shopt extglob
),请执行rm -rf !(README|LICENSE)
。(虽然extglob
尚未启用,但在执行命令之前!(...)
由历史扩展来评估;由于此操作可能失败,因此将执行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
。
我选择备份目录位于根目录中,因为如果您尝试从根目录递归删除所有内容,则系统将遇到很大问题。
当然,有更优雅的方法可以做到这一点,但是这一方法非常简单。
find . | egrep -v "\.tex|\.bib" | xargs rm
find . -maxdepth 1 | grep -v "exclude these" | xargs rm -r
可以更快地工作,因为它不需要不必要地深入到目录。
find
流水线:除了效率问题(find
单独使用3条命令),这对于带有嵌入式空格的文件名将无法正常工作,并且可能会删除错误的文件。
/tmp_backup
),则该命令如果中断就会无法正常工作-从用户的角度来看,所有文件都消失了,除非他们知道去哪里寻找它们以将其取回。因此,我不赞成这种策略。
假设具有这些名称的文件存在于目录树中的多个位置,并且您想保留所有这些文件:
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会忽略通配符(如“ ls *”或“ rm *”)中的php和sql。因此,在设置变量后使用“ rm *”将仅删除txt和tar.gz文件。
GLOBIGNORE
变量的更简单替代方法是使用子外壳程序:(GLOBIGNORE='*.php:*.sql'; rm *)
我更喜欢使用子查询列表:
rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`
-v,--invert-match选择不匹配的行
\|
分隔器
由于没有人提到它:
cp
或rsync
保留权限的适当开关。无论如何,这只是替代方法(作为建议),在此已作为OP的答案。
:)
。
对于OP来说有点晚了,但希望对后来被google赶到这里的人有用...
我发现@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 -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public)
但是带有空格的名称(一如既往)很难。也尝试使用Virtualbox\ VMs
引号。它总是删除该目录(Virtualbox VMs
)。
rm !(myfile.txt)
删除所有包括myfile.txt
shopt -s extglob
首先执行@ pl1nk指出的
使文件不可变。甚至不允许root用户删除它们。
chattr +i textfile.txt backup.tar.gz script.php database.sql info.txt
rm *
所有其他文件已被删除。
最终,您可以将它们重置为可变的。
chattr -i *
这类似于@ 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
由于尚无人提及,因此在一种特定情况下:
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中不起作用)
与其直接发送命令,不如将所需文件移至当前目录之外的temp目录。然后使用rm *
或删除所有文件rm -r *
。
然后将所需文件移到当前目录。
删除所有不包括file.name的内容:
ls -d /path/to/your/files/* |grep -v file.name|xargs rm -rf