0

私が作成した 1 つのスクリプトで問題が発生しました。実行時間が長すぎます (24 分など) が、時間は可変 (ログによって異なります) であり、近い将来、時間は確実に増加します。

トラブルはネストされた for ループにあります。

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;
}

問題は、20k を超える $totalLogsErrores にあります...

他の方法でこれを行うことはできますか?

ありがとうございます!

----------------------- 編集 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
4

4 に答える 4

0

ループによる非効率的な処理

実際に解析しようとしていることを示すコーパスやサンプル出力がないため、ここで実際に何をしようとしているのかを理解することはほとんど不可能です。ただし、この問題は、非効率的な処理とプロセスのフォークに要約できます。

レコード指向の操作にAWKを使用する

ログファイルは一般にレコード指向であり、各行は複数のフィールドを持つレコードです。これがあなたのユースケースである場合、AWK(またはAWKエミュレーションモードのPerl / Ruby)は通常その仕事に適したツールです。これにより、各行を1回だけ処理できるようになり、行の読み取りとフィールドの分割が非常に効率的になります。

たとえば、Bash4とGNUawk(別名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にループと行の解析を1つのプロセスで処理させることにより、大幅な効率が得られる可能性があります。

于 2012-07-18T15:10:59.977 に答える
0

Yoは、ファイル全体をシェル変数に読み込んでから、個別のカットプロセスですべての行を抽出しています。これは非常に非効率的です。

あなたが何をしようとしているのかを解読するのは難しいです。たぶん、関数を次のようなものに置き換えることができます。

$ 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
于 2012-07-18T10:17:20.310 に答える
0

このパフォーマンスの問題を特定するには、次のことを試してください。

find最初の&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回のループがある場合、それには多くの時間がかかります:)

于 2012-07-18T09:44:46.620 に答える