删除所有文件/目录,但保留两个特定目录

5 投票
10 回答
13388 浏览
提问于 2025-04-15 11:35

看起来有很多问题在问怎么删除符合特定条件的文件或文件夹,但我想要的正好相反:删除文件夹中所有不符合我提供的例子的东西。

比如,这里有一个示例目录结构:

.
|-- coke
|   |-- diet
|   |-- regular
|   `-- vanilla
|-- icecream
|   |-- chocolate
|   |-- cookiedough
|   |-- cupcake
|   |   |-- file1.txt
|   |   |-- file2.txt
|   |   |-- file3.txt
|   |   |-- file4.txt
|   |   `-- file5.txt
|   `-- vanilla
|-- lol.txt
|-- mtndew
|   |-- classic
|   |-- codered
|   |-- livewire
|   |   |-- file1.txt
|   |   |-- file2.txt
|   |   |-- file3.txt
|   |   |-- file4.txt
|   |   `-- file5.txt
|   `-- throwback
`-- pepsi
    |-- blue
    |-- classic
    |-- diet
    `-- throwback

我想删除除了 test/icecream/cupcake/ 和 test/mtndew/livewire/ 里的文件之外的所有东西。其他的都可以删除,包括文件夹的结构。所以,我该怎么做呢?我希望能用 bash 或 python 来实现。

10 个回答

3

“除了”这个概念就是我们为什么需要使用if语句的原因;同时,这也是为什么os.walk返回的目录列表是一个可以改变的列表。

for path, dirs, files in os.walk( 'root' ):
    if 'coke' in dirs:
        dirs.remove('coke')
        dirs.remove('pepsi')
6

这个命令会把你想要的文件留在它们原来的文件夹里:

find test \( ! -path "test/mtndew/livewire/*" ! -path "test/icecream/cupcake/*" \) -delete

不需要用到cpio。它在Ubuntu、Debian 5和Mac OS X上都能用。

在Linux上,它会提示你不能删除非空的文件夹,这正是我们想要的结果。而在Mac OS X上,它会默默地完成这个操作。

4

提到 find-prune 选项,但要让它在特定路径(比如 icecream/cupcake/)上工作,确实挺麻烦的,因为它通常是针对特定目录(比如 cupcake/)来使用的。

我个人的做法是直接使用 cpio,然后用硬链接(这样就不用真正复制文件了)把你想保留的目录里的文件链接到一个新的位置,然后再删除旧的目录:

find test -path 'test/icecream/cupcake/*' -o -path 'test/mtndew/livewire/*' | cpio -padluv test-keep
rm -rf test

这样做还能保持你想保留的目录的原有结构。

撰写回答