最小/最大/平均取引期間を計算すると、出力から最も短い取引のIDがありません。

最小/最大/平均取引期間を計算すると、出力から最も短い取引のIDがありません。

Unixコマンドを使用して解析する必要があるログファイルがあります。

行間の時間差を計算し、最後にトランザクション間のMIN、MAX、およびAVG時間とMINのID番号を表示する必要があります。

私のスクリプトは私が書いたすべてのことを行い、MINのID番号を受け入れますが、その理由を理解できません。

  • ログファイルの例:
    03/22 08:51:01.050 INFO :1000 :.main: *************** RSVP Agent started ***************
    03/22 08:51:01.532 INFO :1001 :...locate_configFile: Specified configuration file: /u/user10/rsvpd1.conf WARNING
    03/22 08:51:01.405 INFO :1002 :.main: Using log level 511
    03/22 08:51:01.970 INFO :1003 :..settcpimage: Get TCP images rc - EDC8112I Operation not supported on socket.
    03/22 08:51:01.837 INFO :1004 :..settcpimage: Associate with TCP/IP image name = TCPCS
    03/22 08:51:02.100 INFO :1005 :..reg_process: registering WARNING process with the system
    03/22 08:51:02.524 INFO :1006 :..reg_process: attempt OS/390 registration
    03/22 08:51:02.748 INFO :1007 :..reg_process: return from registration rc=0
    03/22 08:51:06.624 TRACE :1008 :.....starting_transaction: calling API: status: START
    03/22 08:51:06.123 INFO :1009 :...read_physical_netif: index #0, interface VLINK1 has address 129.1.1.1, ifidx 0
    03/22 08:51:06.524 INFO :1010 :...read_physical_netif: index #1, interface TR1 has address 9.37.65.139, ifidx 1
    03/22 08:51:06.367 INFO :1011 :...read_physical_netif: index #2, interface LINK11 has address 9.67.100.1, ifidx 2
    03/22 08:51:06.748 INFO :1012 :...read_physical_netif: index #3, interface LINK12 has address 9.67.101.1, ifidx 3
    03/22 08:51:06.965 INFO :1013 :...read_physical_netif: index #4, interface CTCD0 has address 9.67.116.98, ifidx 4
    03/22 08:51:06.010 INFO :1014 :...read_physical_netif: index #5, interface CTCD2 has address 9.67.117.98, ifidx 5
    03/22 08:51:06.050 INFO :1015 :...read_physical_netif: index #6, interface LOOPBACK has address 127.0.0.1, ifidx 0
    03/22 08:51:06.100 INFO :1016 :....mailslot_create: creating mailslot for timer
    03/22 08:51:06.724 INFO :1017 :.....ending_transaction: calling API: status: END
    03/22 08:51:06.970 INFO :1018 :.....mailslot_create: creating mailslot for RSVP
    03/22 08:51:06.160 INFO :1019 :....mailbox_register: mailbox allocated for rsvp
    
  • 私のスクリプト:
    for i in log-file.txt
    do
      cat log-file.txt | grep -E "starting_transaction|ending_transaction" >> transactions.txt | awk '{print $2}' <transactions.txt >global-time.txt
    
      awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }' <global-time.txt >seconds-time.txt
    
      awk 'NR > 1 { print $0 - prev } { prev = $0 }' <seconds-time.txt >difference-time.txt
    
      awk '{print $4}' <transactions.txt >trans-id.txt | paste difference-time.txt trans-id.txt > diff-transid.txt
    
      awk '{if(min==""){min=max=$1 $2}; if($1>max) {max=$1 $2}; if($1<min) {min=$1 $2}; total+=$1; count+=1} END {print "avg " total/count," | max " max," | min " min " | minID " $2}' <diff-transid.txt >final-answer.txt
    
    done
    
  • 私が得た結果は次のとおりです。
    avg 11.1467  | max 99.1  | min 0.1 | minID
    
  • 私が必要とする結果は次のとおりです。
    avg 11.1467  | max 99.1  | min 0.1 | minID 1017
    

ベストアンサー1

達成したいことはawkスクリプトで完全に行うことができ、これはテキスト処理にシェルループを使用するよりもはるかに効率的です。私は次のプログラムをお勧めします(私たちはこれをと呼びますanalyze_timing.awk):

#!/usr/bin/awk -f

function timediff(start,end,    stfld,endfld,diff) {
    split(start,stfld, /:/)
    split(end,  endfld,/:/)

    if (endfld[1]<stfld[1]) {
        diff=(3600*(endfld[1]+24) + 60*endfld[2] + endfld[3])
    }
    else {
        diff=(3600*endfld[1] + 60*endfld[2] + endfld[3])
    }

    diff -= (3600*stfld[1] + 60*stfld[2] + stfld[3])
    return diff
}


$5 ~ /^:\.+starting_transaction/ {laststart=$2;next}

$5 ~ /^:\.+ending_transaction/ {
    n_transact++
    duration=timediff(laststart, $2)
    avg+=duration
    
    if (n_transact==1) {
        shortest=duration
        longest=duration
        min_id=substr($4,2)
    }
    else {
        if (duration<shortest) {
            shortest=duration
            min_id=substr($4,2)
        } else if (duration>longest) {
            longest=duration
        }
    }
}

END {
    printf("avg: %f | max: %f | min: %f | minID: %d\n", avg/n_transact, longest, shortest, min_id)
}

timediff()例に示すように、最初に2つのタイムスタンプ間の経過時間を計算する関数を定義します。単純化のために、トランザクションが24時間以内に完了すると仮定します。

starting_transaction次に、行の5番目のフィールドがa:とランダムな数字で始まることを確認し、.変数に時間を記録しますlaststart。 5番目のフィールドもで始まる場合は、ending_transaction差を計算しlaststart、最小/最大/平均を計算するために使用される変数を入力します。これまでの取引の中で最も短い取引であれば、IDが に記録されますmin_id

最後に、プログラムは必要に応じて要約を印刷します。

あなたはそれを呼ぶでしょう

awk -f analyze_timing.awk log-file.txt

おすすめ記事