使用排除列表在 bash 中查找目录
现在,在您思考“以前已经这样做过”之前,请继续阅读。
像大多数尝试执行 find 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" 不喜欢我使用所有这些 find -path 或 -o 选项。这是否意味着我必须再次使用 eval ?
我试图在这里使用 bash 的力量,而不是一些 for 循环。任何建设性的意见将不胜感激。
now before you think, "this has been done before" please read on.
Like most of the people trying to do a find bash script you end up hard-coding the script to a single line command, but end up editing the thing over the following months/years so often that you wish in the end you did it right the first time.
I am writing a little backup program right now to do backups of directories and need to find them, against a list of directorie's that needs to be excluded. Easier said than done. Let me set the stage:
#!/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
Now at the end of this you get /cgi-bin,/tmp,/test,/html,/icons
This proves that the concept works, but now to take it a bit further I need to use find to search the BasePath and search only one level deep for all subdirectories and exclude the list of subdirectories in the array...
If I type this by hand it would be:
find /var/www/* \( -path '*/cgi-bin' -o -path '*/tmp' -o -path '*/test' -o -path '*/html' -o -path '*/icons' \) -prune -type d
And should I maybe want to loop into each subdirectory and do the same... I hope you get my point.
So What I am trying to do seem possible, but I have a bit of a problem, printf ",%s" doesn't like me using all those find -path or -o options. Does this mean I have to use eval again?
I am trying to use the power of bash here, and not some for loop. Any constructive input would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试类似的事情
,看看会发生什么。
编辑:如示例中所示,将前导 * 添加到每个路径中。
这是根据您的描述提供的完整解决方案。
$basepath 的子目录不包括 $ignore 中列出的子目录,假设 $ignore 中至少有两个(修复这个问题并不难)。
Try something like
and see what happens.
EDIT: added the leading * to each path as in your example.
And here's a complete solution based on your description.
Subdirectories of $basepath excluding those listed in $ignore, presuming at least two in $ignore (fixing that is not hard).
当给定的目录名称包含文字空格时,现有的答案是有问题的。安全可靠的做法是使用循环。如果您关心的是利用“bash 的力量”——我认为一个强大的解决方案比有缺陷的解决方案更强大。 :)
The existing answers are buggy when given directory names that contain literal whitespace. The safe and robust practice is to use a loop. If your concern is leveraging "the power of bash" -- I'd argue that a robust solution is more powerful than a buggy one. :)
感谢@Sorpigal 我有一个解决方案。我最终嵌套了命令替换,这样我就可以在 cron 中使用脚本,最后在所有脚本周围添加了数组定义。一个已知的问题是目录名称中包含空格。然而,这个问题已经解决了,所以为了保持简单,我认为这回答了我的问题。
Thanks to @Sorpigal I have a solution. I ended up nesting the command substitution so I can use the script in a cron, and finally added the Array definition around all of it. A known problem would be a directory containing a space in the name. This however has been solved, so trying to keep it simple, I think this answers my question.