我需要使用每日脚本删除文件夹内的所有文件夹。当天的文件夹需要保留。
文件夹“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
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
另一个命令。