太长了;博士

太长了;博士

我需要使用每日脚本删除文件夹内的所有文件夹。当天的文件夹需要保留。

文件夹“myfolder”有 3 个子文件夹:“test1”、“test2”和“test3”,我需要删除除“test2”之外的所有子文件夹。

我试图在这里匹配确切的名称:

find /home/myfolder -type d ! -name 'test2' | xargs rm -rf

或者

find /home/myfolder -type d ! -name 'test2' -delete

此命令始终尝试删除主文件夹“myfolder”!有办法避免这种情况吗?

答案1

这将删除./myfolder除该文件夹之外的所有文件夹./myfolder/test2,并且其所有内容将被保留:

find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?' -delete

怎么运行的

  • find启动查找命令。
  • ./myfolder告诉 find 从目录./myfolder及其内容开始。

  • -mindepth 1 不匹配./myfolder自身,只匹配其下的文件和目录。

  • ! -regex '^./myfolder/test2\(/.*\)?' 告诉 find 排除 ( !) 任何与正则表达式匹配的文件或目录^./myfolder/test2\(/.*\)?^匹配路径名的开头。该表达式 (/.*\)?匹配 (a) 斜杠后跟任何内容或 (b) 根本不匹配。

  • -delete 告诉 find 删除匹配的(即非排除的)文件。

例子

考虑一个看起来像这样的目录结构;

$ find ./myfolder
./myfolder
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2

我们可以运行 find 命令(不带-delete)来查看它匹配的内容:

$ find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?'
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3

我们可以通过查看剩余的文件来验证这是否有效:

$ find ./myfolder
./myfolder
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2

答案2

使用bash:

shopt -s extglob
rm -r myfolder/!(test2)/

例子:

$ tree myfolder/
myfolder/
├── test1
│   └── file1
├── test2
│   └── file2
└── test3
    └── file3

$ echo rm -r myfolder/!(test2)
rm -r myfolder/test1 myfolder/test3
$ rm -r myfolder/!(test2)
$ tree myfolder/
myfolder/
└── test2
    └── file2

1 directory, 1 file

答案3

太长了;博士

find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 \
     -exec echo rm -rf '{}' \;

如果对文件列表满意,请删除回显。


使用-mindepth 1将确保顶部未选择目录。

$ find ./myfolder -mindepth 1 -type d
./myfolder/test2
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3

但有一个-not -name test2意志不是避免里面有子目录test2

$ find ./myfolder -mindepth 1 -type d -not -name 'test2'
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3

为此,你需要像 prune 这样的东西:

$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3

不要使用delete,因为它暗示depth并且它将开始从最长路径中删除:

$ find ./myfolder -depth -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test/a1/a2/a3
./myfolder/test/a1/a2
./myfolder/test/a1
./myfolder/test

要么使用(如果你想真正删除则rm -rf删除):echo

$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
rm -rf ./myfolder/test/a1
rm -rf ./myfolder/test/a1/a2
rm -rf ./myfolder/test/a1/a2/a3

或者,maxdepth如果您需要的只是删除目录(以及其中的所有内容),请使用(删除echo以实际擦除):

$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test

-delete如果目录不为空,A仍然会失败:

$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -delete
find: cannot delete ‘./myfolder/test’: Directory not empty

答案4

如果要求仅针对问题中提到的一级(不超过深度 1),那么这是另一个简单的选择:

ls myfolder/ | grep -v "test2" | xargs rm -r

细节:

  • ls myfolder/列出myfolder/目录中的所有文件夹和文件
  • grep -v "test2"匹配除“test2”之外的所有内容
  • xargs rm -r将前一个命令的输出通过管道传输到rm -r另一个命令。

相关内容