在Linux终端中,如何删除一个目录中除了一个或两个文件之外的所有文件?

18
在Linux终端中,如何删除文件夹中除一个或两个文件之外的所有文件?
例如,
我有一个目录中的100个图像文件和一个.txt文件。 我想删除除那个.txt文件以外的所有文件。

除了哪一个或两个? - display-name-is-missing
最好展示一些异常应该长什么样的模式。否则我们只能给出非常笼统的答案。 - fedorqui
5个回答

38

从目录中列出文件,过滤掉所有不包含“file-to-keep”的文件,并删除列表中剩下的所有文件。

ls | grep -v 'file-to-keep' | xargs rm
为避免文件名中出现空格的问题(请记住不要在文件名中使用空格),请使用find-0选项。
find 'path' -maxdepth 1 -not -name 'file-to-keep' -print0 | xargs -0 rm

或者混合使用,使用grep选项-z来管理从find获取的-print0名称。


如果文件名中包含空格,这可能会有问题。 - Martin Ellis
可以运行。我必须在当前目录下才能成功执行这个命令,对吗? - Bilal
我尝试使用sudo ls directory/directory/directory1/ | grep -v 'readme.txt' | xargs rm命令,但是没有起作用。我需要在许多目录上运行此命令。假设我的directory有兄弟目录directory2, directory3 - Bilal
@Bilal 对于以 ls 开头的命令,是的,它将在当前目录中完成任务。如果您使用 find 命令,则可以将许多目录列为 'path' - Didier Trosset
在选项1中,grep需要在此处使用--line-regexp参数,否则/bin/w将匹配/bin/which - Victor Sergienko

9

通常使用grep的倒排模式搜索即可完成工作。由于您没有定义任何模式,我只能给出一个一般性的代码示例:

ls -1 | grep -v 'name_of_file_to_keep.txt' | xargs rm -f
ls -1 命令每行列出一个文件,因此 grep 可以逐行搜索。 grep -v 是反转标志,所以任何匹配的模式都不会被删除。
对于多个文件,可以使用 egrep:
ls -1 | grep -E -v 'not_file1.txt|not_file2.txt' | xargs rm -f

问题更新后的更新: 我假设您愿意删除除当前文件夹中不以.txt结尾的文件以外的所有文件。因此,这个也应该可以工作:

find . -maxdepth 1 -type f -not -name "*.txt" -exec rm -f {} \;

史诗般的。干净的答案。谢谢。 - moeiscool

5

find命令支持-delete选项,因此您不需要使用-exec。您还可以传递多个-not -name somefile -not -name otherfile

user@host$ ls
1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt josh.pdf keepme

user@host$ find . -maxdepth 1 -type f -not -name keepme -not -name 8.txt -delete

user@host$ ls
8.txt  keepme

3
在bash中,您可以使用:
$ shopt -s extglob  # Enable extended pattern matching features    
$ rm !(*.txt)       # Delete all files except .txt files

3

使用not修饰符来删除您不想删除的文件(file(s))模式(pattern(s)),您可以修改传递给-maxdepth1来指定要从中删除文件的子目录深度。

find . -maxdepth 1 -not -name "*.txt" -exec rm -f {} \;

你可以进行以下操作:

find  -maxdepth 1 \! -name "*.txt" -exec rm -f {} \;

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