0

调用以下命令时,我发现它运行缓慢,尽管磁盘、CPU 和内存都没有消耗太多(使用 top / iotop 检查)

find . -type f -size +0 -exec ./work.sh {} \;

我选择了这个特殊的 find 构造,因为我有很多文件(>50k)。

work.sh里面基本上是这样的:

prefix=\"$filename\"";"\"$timestamp\"";"\"
SED_ARG="-e 's/^/"$prefix"/'"
zcat $1 | sed = | sed 'N;s/\n/";/' | grep -vE '"timepassed";' | eval sed "$SED_ARG" >> $logfilename

有哪些方法可以分析或提高性能?我可能会等待 exec 返回每个文件,而它可能只是为下一个文件生成下一个 exec。

4

2 回答 2

2

将作业划分为块并使用 shell 作业控制运行它们。或者安装 GNU 并行,如果这将是一个日常的事情。作业控制示例:

cnt=1
find . -type f -size +0 |
while read fname 
do
   zcat $fname | sed = | sed 'N;s/\n/";/' | grep -vE '"timepassed";' | 
             eval sed "$SED_ARG" >> $logfilename &
   [ $(( $cnt % 10  )) -eq 0 ] && wait
   cnt=$(( $cnt + 1 ))
done
wait

这一次运行十个作业。更改 10 以适合您的系统,更高的数字并不总是更好的选择。

$(( % )) 是模 - 余数 - 算术。所以当 cnt 是 10 20 30 ... $(( $cnt % 10 )) 返回零。每次该值返回零时,脚本都会调用等待。最后一个等待语句(在 done 一词下方)是在循环结束的情况下,该数字不能被 10 整除,例如 52002。这都是 bash 的一部分。

于 2013-03-29T02:55:58.563 回答
0

我认为您执行速度慢的一个原因是您有太多管道命令。如果我理解正确,您的管道命令链可以大大重构为:

zcat $1 | awk -v f="$filename" -v t="$timestamp" '$1 !~ "\"timepassed\";" {
             printf("\"%s\";\"%s\";\"%d\";%s\n", f, t, NR, $0)}' >> $logfilename

一旦你确认上面的代码片段正在做同样的工作,你可以再次尝试你的 find 命令来查看性能。

于 2013-03-29T05:51:36.490 回答