现在,在您认为“这已经完成了”之前,请继续阅读。
像大多数尝试执行查找 bash 脚本的人一样,您最终将脚本硬编码为单行命令,但最终在接下来的几个月/几年内如此频繁地编辑东西,以至于您最终希望第一次就做对了。
我现在正在编写一个小备份程序来备份目录并需要根据需要排除的目录列表找到它们。说起来容易做起来难。让我来布置舞台:
#!/bin/bash
BasePath="/home/adesso/baldar"
declare -a Iggy
Iggy=( "/cgi-bin"
"/tmp"
"/test"
"/html"
"/icons" )
IggySubdomains=$(printf ",%s" "${Iggy[@]}")
IggySubdomains=${IggySubdomains:1}
echo $IggySubdomains
exit 0
现在在这最后你得到/cgi-bin,/tmp,/test,/html,/icons 这证明了这个概念是有效的,但现在更进一步,我需要使用 find 来搜索 BasePath 并只搜索一层深度的所有子目录并排除数组中的子目录列表。 ..
如果我手动输入,它将是:
find /var/www/* \( -path '*/cgi-bin' -o -path '*/tmp' -o -path '*/test' -o -path '*/html' -o -path '*/icons' \) -prune -type d
我是否应该循环进入每个子目录并做同样的事情......我希望你明白我的意思。
所以我尝试做的事情似乎可行,但我有一点问题,printf ",%s" 不喜欢我使用所有那些查找 -path 或 -o 选项.这是否意味着我必须再次使用 eval?
我在这里尝试使用 bash 的强大功能,而不是一些 for 循环。任何建设性的意见将不胜感激。
最佳答案
尝试类似的东西
find /var/www/* \( -path "${Iggy[0]}" $(printf -- '-o -path "*%s" ' "${Iggy[@]:1}") \) -prune -type d
看看会发生什么。
编辑:在您的示例中将前导 * 添加到每个路径。
根据您的描述,这是一个完整的解决方案。
#!/usr/bin/env bash
basepath="/home/adesso/baldar"
ignore=("/cgi-bin" "/tmp" "/test" "/html" "/icons")
find "${basepath}" -maxdepth 1 -not \( -path "*${ignore[0]}" $(printf -- '-o -path "*%s" ' "${ignore[@]:1}") \) -not -path "${basepath}" -type d
$basepath 的子目录不包括在 $ignore 中列出的那些,假设至少有两个在 $ignore 中(修复它并不难)。
关于linux - 使用排除列表在 bash 中查找目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8139523/