2012-01-05 70 views
3

我有一个bash脚本,它基于用户输入来压缩文件名。它工作得很好,尽管速度很慢,因为我有时会分析多达5万个文件。改进查找性能

find "$DIR" -name "$USERINPUT" -print | /usr/bin/zip -1 SearchResult [email protected] 

这里的@符号表示zip将接受来自STDIN的文件名。有没有办法让它变得更快?

我正在考虑创建一个cron作业来每天晚上更新locate数据库,但我不是root用户,所以即使它是值得的。

欢迎任何建议。

+0

首先,我到美分:'type -d'会让'find'只查找文件夹,所以原则上它应该会有所不同。难道说'zip'是这里的瓶颈吗?我会用'tar czf'做一个测试insted来压缩文件,看看性能是否更好。 – 2012-01-05 00:44:31

+0

很可能'zip'是问题:我选择它是因为数据上的用户是严格的窗口用户。我不知道GZIP或TAR是否可以在MS窗口上创建任何可读的内容。任何输入欢迎。 – Chris 2012-01-05 00:46:52

+0

很难说出什么是瓶颈。你真的应该首先分析这两个步骤,通过与压缩文件分开生成文件列表,将其放入临时文件而不是管道。然后在每一步之前和之后调用'date'。 – mvds 2012-01-05 01:26:59

回答

0

听起来就像你在拖拽文件系统,为50,000个文件中的每一个文件运行查找。

为什么不做one运行find命令,记录文件系统中所有文件的名称,然后从这个日志文件中直接获取它们的位置?

或者,将工作分解为独立的作业,特别是如果您有多个文件系统和多个CPU。您的方法不需要单线程。

+2

他的find-oneliner会在一个块中生成所有匹配的文件名,并且不会逐个文件地调用zip。他使用 - @参数(从STDIN获取文件列表)将这个列表压缩成zip文件,并且使用-1进行最小压缩(尽管对于可能尝试的NO压缩有-0))。 – 2012-01-05 02:55:12

0

正如Mattias Ahnberg指出的那样,在调用zip之前,使用find将生成匹配文件的完整列表。如果你正在做这个超过50,000个文件,那需要一些时间。也许更合适的方法是使用find-exec <cmd> {} \;特点:

find "$DIR" -name "$USERINPUT" -exec /usr/bin/zip -1 {} \; 

通过这种方式,找到所调用拉链本身上的每个匹配的文件。您应该达到与原始版本相同的最终结果,但是如果文件数量太多是您的瓶颈(如果文件很小,最有可能),这会在开始查找匹配时立即启动运行的zip ,而不是在找到所有的比赛时。

注意:我建议阅读手册页以查找有关此选项的详细信息。请注意,分号必须转义以防止shell解释它,而不是将其传递给查找。

1

我建议你在xargs命令中使用并行处理来加速你的整个过程。使用如下命令:

find "$DIR" -name "$USERINPUT" -print0 | xargs -0 -P10 zip -1 SearchResult [email protected] 

以上命令将使xargs运行10个并行子进程。

请记录上述命令的时间是这样的:

time find "$DIR" -name "$USERINPUT" -print0 | xargs -0 -P10 zip -1 SearchResult [email protected] 

,看看这使得任何性能改进。

+0

哇,好主意。我会刺穿它并更新这个线程。谢谢。 – Chris 2012-01-26 23:16:21