删除文件夹中的所有文件夹,但具有特定名称的文件夹除外

Rij*_*hna 30 linux find delete

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

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

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

find /home/myfolder -type d ! -name 'test2' | xargs rm -rf
Run Code Online (Sandbox Code Playgroud)

或者

find /home/myfolder -type d ! -name 'test2' -delete
Run Code Online (Sandbox Code Playgroud)

此命令也总是尝试删除主文件夹“myfolder”!有没有办法避免这种情况?

Joh*_*024 49

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

find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?' -delete
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

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

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

  • ! -regex '^./myfolder/test2\(/.*\)?' tells find to exclude (!) any file or directory matching the regular expression ^./myfolder/test2\(/.*\)?. ^ matches the start of the path name. The expression (/.*\)? matches either (a) a slash followed by anything or (b) nothing at all.

  • -delete tells find to delete the matching (that is, non-excluded) files.

Example

Consider a directory structure that looks like;

$ 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
Run Code Online (Sandbox Code Playgroud)

We can run the find command (without -delete) to see what it matches:

$ 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
Run Code Online (Sandbox Code Playgroud)

We can verify that this worked by looking at the files which remain:

$ find ./myfolder
./myfolder
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2
Run Code Online (Sandbox Code Playgroud)


Jef*_*ler 13

Using bash:

shopt -s extglob
rm -r myfolder/!(test2)/
Run Code Online (Sandbox Code Playgroud)

Example:

$ 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
Run Code Online (Sandbox Code Playgroud)


ImH*_*ere 6

tl;dr

find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 \
     -exec echo rm -rf '{}' \;
Run Code Online (Sandbox Code Playgroud)

Remove echo if satisfied with the list of files.


使用-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
Run Code Online (Sandbox Code Playgroud)

-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
Run Code Online (Sandbox Code Playgroud)

要做到这一点,你需要像 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
Run Code Online (Sandbox Code Playgroud)

但是不要使用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
Run Code Online (Sandbox Code Playgroud)

要么使用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
Run Code Online (Sandbox Code Playgroud)

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

$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
Run Code Online (Sandbox Code Playgroud)

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

$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -delete
find: cannot delete ‘./myfolder/test’: Directory not empty
Run Code Online (Sandbox Code Playgroud)