我遇到了一个我做过的脚本有问题,时间执行太长(比如24分钟),但时间是可变的(取决于日志),并且在不久的将来时间肯定会增加
这个问题正在进行中:
obtener_ErroresLanzados()
{
#Buscamos los equipos del log lanzados_a_pendientes en los logs de instala_sw_qcc para ver el porque no se han lanzado.
totalLanzadosPendientes=`cat $rutaTemporales/lanzados_a_pendientes.log | wc -l`;
lanzadosPendientes=$(cat $rutaTemporales/lanzados_a_pendientes.log);
#grep "$paqueteBuscado" instala_sw_qcc_2012*.log | cut -f 1 -d ":" > $rutaTemporales/logsErrores.log;
find $rutaTrazas -name "instala_sw_qcc_2012*" | xargs grep -l "$rutaQcc/$paqueteBuscado" | xargs grep -l "ERROR \[" | cut -f 9 -d "/" > $rutaTemporales/logsErrores.log;
logsErrores=$(cat $rutaTemporales/logsErrores.log);
totalLogsErrores=`cat $rutaTemporales/logsErrores.log | wc -l`;
for (( j=1; j<=$totalLanzadosPendientes; j++ ))
do
equipoBusqueda=`echo $lanzadosPendientes | cut -f $j -d " "`;
for (( k=1; k<=$totalLogsErrores; k++ ))
do
logBusqueda=`echo $logsErrores | cut -f $k -d " "`;
grep "ERROR \[$equipoBusqueda\]" $rutaTrazas/$logBusqueda >> $rutaTemporales/erroresPendientes.log;
if [ $? -eq 0 ];then
break;
fi;
done;
done;
cat $rutaTemporales/erroresPendientes.log | sed 's/ / /g' | sed '/No se ha podido/d' | cut -f 7-14 -d " " | sort -u > $rutaTemporales/erroresPendientes_Final.log;
}
问题是$ totalLogsErrores大于20k ......
我可以通过其他方式这样做吗?
谢谢!
-----------------------编辑1 ---------------------- -
$ time find $rutaTrazas -name "instala_sw_qcc_2012*" | xargs grep -l "$rutaQcc/$paqueteBuscado" | xargs grep -l "ERROR [" | cut -f 9 -d "/"
real 0m3.862s
user 0m0.959s
sys 0m2.941s
$ du -h ../trazas/instala_sw_qcc_20120718091838.log
4.0K ../trazas/instala_sw_qcc_20120718091838.log
$ time grep error ../trazas/instala_sw_qcc_20120718091838.log
real 0m0.001s
user 0m0.001s
sys 0m0.000s
答案 0 :(得分:0)
要确定此性能问题,您可以尝试以下操作:
评估您的第一个find
&amp; grep
命令:
$ time find $rutaTrazas -name "instala_sw_qcc_2012*" | xargs grep -l "$rutaQcc/$paqueteBuscado" | xargs grep -l "ERROR \[" | cut -f 9 -d "/" > $rutaTemporales/logsErrores.log;
在嵌套的for
循环中,评估grep
的影响。文件有多大?在您的评论中,您提到了100*10000
重复,如果每个grep
花费4毫秒,这将是巨大的。
当您拥有大量子目录时,find
会变得昂贵,而当您的文件足够大时,grep
会变得昂贵。
$ du -h file.out
20K file.out
$ time grep ERROR file.out
real 0m0.004s
user 0m0.000s
sys 0m0.003s
如果你有1000000个循环,那将需要很多:)
答案 1 :(得分:0)
无用的猫:wc -l <file
而不是cat file | wc -l
无用的使用wc:while read line; do ...;done <file
而不是for循环:
find $rutaTrazas -name "instala_sw_qcc_2012*" | xargs grep -l "$rutaQcc/$paqueteBuscado" | xargs grep -l "ERROR \[" | cut -f 9 -d "/" > $rutaTemporales/logsErrores.log;
while read equipoBusqueda; do
while read logBusqueda; do
grep "ERROR \[$equipoBusqueda\]" $rutaTrazas/$logBusqueda >> $rutaTemporales/erroresPendientes.log
if [ $? -eq 0 ];then
break;
fi;
done <$rutaTemporales/logsErrores.log
done <$rutaTemporales/lanzados_a_pendientes.log
cat $rutaTemporales/erroresPendientes.log | sed 's/ / /g' | sed '/No se ha podido/d' |
cut -f 7-14 -d " " | sort -u > $rutaTemporales/erroresPendientes_Final.log;
最终查找,grep,sed,cut等命令可能会被简化。
答案 2 :(得分:0)
Yo正在将整个文件读入一个shell变量,然后使用一个提取每一行 单独的切割过程。这是非常低效的。
很难破译你想要做什么。也许你可以替换这个功能 用这样的东西:
$ cd $rutaTrazas
$ sed 's/^/ERROR \[/; s/$/\]/' $rutaTemporales/lanzados_a_pendientes.log > search_strings
$ xargs grep -F -f search_strings \
< $rutaTemporales/logsErrores.log \
>> $rutaTemporales/erroresPendientes.log
$ < $rutaTemporales/erroresPendientes.log \
sed 's/ / /g' | sed '/No se ha podido/d' |
cut -f 7-14 -d " " |
sort -u > $rutaTemporales/erroresPendientes_Final.log
答案 3 :(得分:0)
几乎不可能弄清楚你真正想要在这里做什么,因为没有语料库或示例输出显示你实际想要解析的内容。但是,您可以将此问题归结为低效处理和处理分叉。
日志文件通常是面向记录的,其中每一行都是具有多个字段的记录。如果这是您的用例,则AWK(或AWK仿真模式下的Perl / Ruby)通常是该工作的正确工具。这确保您只处理每一行,并且读取行和拆分字段非常有效。
例如,使用Bash 4和GNU awk(a.k.a. gawk):
shopt -s globstar
awk 'BEGIN {error_count = 0}
/ERROR/ {print $9; ++error_count}
# other pattern/action pairs
END {print "Total errors:", error_count}
' **/instala_sw_qcc_2012* > /path/to/output/file
如果您确实需要,可以将多个模式匹配应用于每一行,或者直接输出到awk内部的单个文件。但是,通过让awk在一个进程中处理循环和行解析,您可能会获得很高的效率。