我的服务器中有 100 个 joomla 网站,我想清理所有 joomla 缓存文件夹。我需要一个命令来执行此操作:
1-查找所有具有“cache”名称的目录
如果我搜索例如“/home/demo/”目录
它在最多更深一层找到“缓存”目录,例如:
/home/demo/ddf3e/
/home/demo/awda2/
没有比这个更深的了
2-清理“缓存”目录内的所有文件和目录
仅删除要删除的内容不是它本身
3-在所有“cache”目录中创建一个“index.html”文件
先感谢您
答案1
最 POSIX 的方法可能是使用find
带有多个-exec
选项的命令。
更新:完整的 POSIX 解决方案位于本文末尾。
您可以在路径下找到名为“cache”的嵌套目录,/home/demo
如下所示:
find /home/demo -mindepth 2 -maxdepth 2 -type d -name cache
mindepth
和maxdepth
值2
将搜索限制为直接子目录-type d
指定您只想查找目录-name cache
告诉它只返回名称完全为“cache”的匹配项
然后,您可以使用该-exec
选项根据匹配的结果执行操作。例如,如果您想运行ls
以列出每个匹配的缓存目录的内容:
find /home/demo -mindepth 2 -maxdepth 2 -type d -name cache -exec ls {} \;
-exec
ls
对于每场比赛,调用 ( ) 后面的以下命令{}
返回匹配的值(在本例中为缓存目录的路径)\;
告诉它每场比赛执行一次命令
因此,如果您想删除该目录的内容,您可以将ls
上面的命令替换为适当的rm
语句,例如sh -c 'rm "{}"/*'
示例(不要运行这个):
find /home/demo -maxdepth 2 -mindepth 2 -type d -name cache -exec sh -c 'rm "{}"/* 2>/dev/null' \;
在上面的示例中sh -c
,用于允许 shell 扩展以/*
匹配嵌套文件(尽管这不是很 POSIX)。然后您还可以添加另一个文件-exec
来创建附加文件。
示例(不要运行这个):
find /home/demo -maxdepth 2 -mindepth 2 -type d -name cache -exec sh -c 'rm "{}"/* 2>/dev/null' \; -exec touch "{}/index.html" \;
在上面的示例中,两个-exec
选项一起使用。第二个命令创建嵌套index.html
文件,仅在第一个-exec
命令成功完成时运行。
不过,最好将其拆分为多个查找命令,一个用于匹配和删除文件,另一个用于创建index.html
.
示例(不要运行这个):
find /home/demo -mindepth 3 -maxdepth 3 -wholename "/home/demo/*/cache/*" -exec rm -rf "{}" \;
find /home/demo -maxdepth 2 -mindepth 2 -type d -name cache -exec touch "{}/index.html" \;
在第一个声明中:
-mindepth
并且-maxdepth
只3
匹配孩子的孩子-wholename "/home/demo/*/cache/*"
提供与目标缓存目录的子目录的匹配
然后第二条语句创建index.html
文件。
如果我正确理解你的问题,那么该命令对大概做你正在寻找的事情。但在使用前请仔细阅读并确保完全理解。
我建议在运行任何内容之前在任何命令前面加上命令rm
前缀。这应该可以让您进行一次演练,看看它在做什么。touch
echo
示例(使用 进行安全试运行echo
):
find /home/demo -mindepth 3 -maxdepth 3 -wholename "/home/demo/*/cache/*" -exec echo rm -rf "{}" \;
find /home/demo -maxdepth 2 -mindepth 2 -type d -name cache -exec echo touch "{}/index.html" \;
更新 - 完全 POSIX 解决方案(但更难阅读):
对于完全 POSIX 等效项(无mindepth
/ maxdepth
/ ),您可以使用的内部通配符来wholename
使用正/负-path
组合。find
如果您首先进入工作树,则会容易得多cd
,因为您不必计算 glob 模式的主要目录。
cd /home/demo
find . -path "./*/cache/*" ! -path "./*/*/*/*" -exec echo rm -rf {} \;
find . -type d -path "./*/cache" ! -path "./*/*/*" -exec echo touch {}/index.html \;
echo
如果得到预期结果,请删除这些语句。
答案2
所以,如果我没猜错的话,你想找到 的/home/demo/foo/cache
所有值的eg foo
。由于您不需要深入研究,因此相当简单。
(1) 您可以使用 shell glob 列出它们:
$ cd /home/demo
$ echo */cache
为了防止像那些以破折号(-foo
)开头的有趣名称,我们最好使用./*
。另外,在 bash 中,您还可以使用 使 glob 包含以点开头的名称shopt -s dotglob
。
(2) 查找并删除目录中的文件(使用 GNU find-mindepth 1
可以防止其与目录本身匹配):
$ shopt -s dotglob
$ find ./*/cache -mindepth 1 # list them
./awda2/cache/foo
[...]
$ find ./*/cache -mindepth 1 -delete # delete them...
您也可以仅使用rm
,但对于大量文件,您可能会超出命令行长度的限制。
$ rm -r ./*/cache/*
(3) 创建或复制一个文件到所有这些(touch
创建一个空文件):
$ for dir in ./*/cache ; do touch "$dir/index.html" ; done
$ for dir in ./*/cache ; do cp index.html.model "$dir/index.html" ; done
(如果有一个文件(不是目录)named cache
,你会得到一个无害的错误。)