1

これを行うより高速な方法を知っている人はいますか? これは現在、このスクリプトに 1 秒あたりの高い行数をプッシュすると遅くなります。


#!/bin/bash

declare -A clientarray
file=$1
timer=$2
e=$(date --date "now +$timer second" +%s)

while read line
do

    if [ -n "${clientarray[$line]}" ]; then
            let "clientarray[$line]=clientarray[$line]+1"
            echo "$line: ${clientarray[$line]}"

    elif [ -z "${clientarray[$line]}" ]; then
            clientarray[$line]=1
            echo "$line: ${clientarray[$line]}"

    fi
    if [ $(date +%s) -gt $e ]; then
                    e=$(date --date "now +$timer second" +%s)

    fi
done < <(tail -F $file | gawk -F"]" '/]/ {print $1}')

次に、行の例を示します。

someline]
someline2]
somethingidontwant
someline3]
somethingelseidontwant
someline4]

そしてスクリプトを呼び出すには:

bash script.sh somelogfile.log 1

最後にifロジックをコメントアウトすると、非常に高速になりますが、速度が2/3低下します。pvでテストしました:

(これは if ロジックを使用したものです):

ubuntu@myhost:~/graphs$ tail -F somelogfile.log | pv -N RAW -lc >/dev/null | 
                      > bash script.sh somelogfile.log 1 | pv -N SCP -lc >/dev/null

  RAW: 2.18k 0:00:16 [ 493/s ] [                 <=>                             ]
  SCP:  593 0:00:16 [ 150/s ] [             <=>                                  ]

(これはなしです)

ubuntu@myhost:~/graphs$ tail -F somelogfile.log | pv -N RAW -lc >/dev/null |
                      > bash script.sh somelogfile.log 1 | pv -N SCP -lc >/dev/null

  RAW: 7.69k 0:00:15 [512/s] [                                     <=>           ]
  SCP:  7.6k 0:00:15 [503/s] [                              <=>                  ]

スクリプトまたはテスト側で何か不足している場合、特に「DOH!」があれば教えてください。この時点で、私は1つが好きだと思います=)

4

2 に答える 2

2

if推測として、最後の...fiブロックが反復ごとに 2 つの非組み込みコマンドを追加する可能性があると思います。ループ内の他のすべては、はるかに高速に実行される bash ビルトインです。dateこれにより、テスト内でへの呼び出しがあり、 if. さらに、は呼び出されるたびにdate --dateその式を解析して評価する必要があります。もし私があなたなら、日付/時刻をよりネイティブに処理するスクリプト言語でこれを再実装してみます: Perl、Ruby、Python など、あなたが慣れているものなら何でも。"now +$timer second"--date

あなたにもバグがあるようです:

if [ `date +%s` > $e ] ...

これは、コマンドを実行し、その出力 (たとえば) を別のコマンドdate +%sに補間する(これまでのところ非常に良い) ことを示しています。そのコマンドは、次のように述べています。2 つの引数 (および) を指定してビルトインを実行し、その標準出力ストリームを(uh-oh)の値で名前が付けられたファイルにリダイレクトします。おそらくここの代わりに使いたいでしょう。12345[ 12345 > $e ][12345]$e-gt>

于 2012-04-26T18:23:10.753 に答える
0

で何をしているのかわかりませんが$e、シェルのビルトインを使用するprintfと、 を呼び出すよりもはるかに高速に現在の日付を出力できますdate。サブプロセスの呼び出しは、コストがかかる傾向があります。たとえば、glibc2 を使用していない場合は、次のようにできます。

printf '%(%+)T\n' -1

date コマンドの出力を正確に取得します。%+glibc2 ではサポートされていないため、他のパラメーターと同じもの、または次のようなものを構築できます。

printf '%(%c %Z)T\n' -1

何らかの方法で日付を取得して処理する必要がある場合でも、 を使用したサブシェル呼び出しが必要になる場合がありますが$()date.

于 2014-09-03T07:48:32.577 に答える