find -name "lastStable" -o -name "lastSuccessful" -exec sh -c "sudo rm -rv {}/*" {} \;
从上面的命令中可以看出,我正在浏览并删除和目录的内容lastStable
,lastSuccessful
但保留这些文件夹。但是在中find
,我可能会得到带有空格的路径,例如:
/promotions/Production Development Environment/lastStable
我如何让我的查找脚本也处理这些带有空格的路径?
答案1
请参阅先前的 unix.se 问题:“可以find -exec sh -c
安全使用吗?”。
当前尝试失败的原因是它直接在参数中替换匹配的文件路径sh -c
;因此,如果匹配的文件路径是“/promotions/Production Development Environment/lastStable”,它将运行相当于:
sh -c "sudo rm -rv /promotions/Production Development Environment/lastStable/*" '/promotions/Production Development Environment/lastStable'
(路径被包含两次,因为{}
在 的参数中出现了两次-exec
。)然后 shell 对给定的命令执行单词拆分,并运行相当于:
sudo rm -rv '/promotions/Production' 'Development' 'Environment/lastStable'/*
...这根本不是你想要的。
{}
但请注意,字符串中第二次出现的-exec
并没有被拆分,您可以利用这一点:
find -name "lastStable" -o -name "lastSuccessful" -exec sh -c 'sudo rm -rv "$0"/*' {} \;
请注意,"$0"
而不是{}
(因此 shell 将执行替换,并且不会进行分词),以及子命令周围的单引号(因此$0
在传递给 shell 之前不会被解释)。这相当于:
sh -c 'sudo rm -rv "$0"/*' '/promotions/Production Development Environment/lastStable'
然后 shell$0
用 shell 命令的下一个参数替换,得到:
sudo rm -rv "/promotions/Production Development Environment/lastStable"/*
据我所知,这正是您想要的。
答案2
尝试:
find . -path "*/lastSuccessful/*" -o -path "*/lastStable/*"
如果看起来它将选择所选路径内的所有文件/目录。
注意必须绝不选择“lastStable”或“lastSuccessful”为最后的目录路径的元素。
然后你可以将命令更改为
find . -path "*/lastSuccessful/*" -delete -o -path "*/lastStable/*" -delete
这将删除这些路径内的所有子目录。
这是可行的,因为-path
匹配整个路径将其评估为一个字符串,但仍然遵守通配符模式。-delete
将对匹配的文件执行必要的删除机制(rmdir 或 unlink)。它不需要特殊处理(空格等),因为您没有将请求传递给 shell(通常会扩展空格或星号等字符)。
答案3
对于那些想知道我如何删除文件夹内容但保留文件夹并处理空格的人,下面是我的做法:
find $PWD -name "lastSuccessful" -o -name "lastStable" -type d -not -empty -print0 | while read -d $'\0' path; do cd "$path"; ls -1 | xargs sudo rm -fvr; done
它的作用:查找我正在搜索的目录的完整路径。CD 到该目录并列出文件,然后删除所有这些文件/文件夹。
答案4
尝试rm --
使用或find -inum
将其通过管道传输到 als -i
以获取 inode #,然后rm -i $inode#