各行の数値と一意の数値を計算して要約するスクリプト

各行の数値と一意の数値を計算して要約するスクリプト
timestamp : IDs returned
20160420084726:-
20160420085418:[111783178, 111557953, 111646835, 111413356, 111412662, 105618372, 111413557]
20160420085418:[111413432, 111633904, 111783198, 111792767, 111557948, 111413225, 111413281]
20160420085418:[111413432, 111633904, 111783198, 111792767, 111557948, 111413225, 111413281]
20160420085522:[111344871, 111394583, 111295547, 111379566, 111352520]
20160420090022:[111344871, 111394583, 111295547, 111379566, 111352520]

タイムスタンプ形式はYYYYMMDDhhmmssです。

·広告は、角かっこで囲まれた広告資産IDのカンマ区切りリストです。または - 広告が返されない場合

1日10分ごとに出力するスクリプトを作成する必要があります。

  1. 返されたIDの数

  2. 返された一意のIDの数

  3. スクリプトは、一意のIDまたは完全なIDを提供する必要があるかどうかを選択するコマンドラインパラメータをサポートする必要があります。

上記のログ抜粋を使用した出力例(合計モード):

20160420084:0
20160420085:26
20160420090:5

固有計算モードでは、以下を提供します。

20160420084:0
20160420085:19
20160420090:5

これが私が今まで持っているものです:

#!/usr/bin/bash
awk -F":" ' { print $1":" $2 } ' file.log | sort -r | uniq -c

結果:

1 20160420090022:[111344871, 111394583, 111295547, 111379566, 111352520] 
1 20160420085522:[111344871, 111394583, 111295547, 111379566, 111352520] 
1 20160420085418:[111783178, 111557953, 111646835, 111413356, 111412662, 105618372, 111413557] 
2 20160420085418:[111413432, 111633904, 111783198, 111792767, 111557948, 111413225, 111413281] 
1 20160420084726:- 
7: –

ベストアンサー1

配列の配列を処理するにはGNU awkを使用してください(length(array)ただし、現在のほとんどのawkはこれを行います):

$ cat tst.awk
BEGIN { FS=OFS=":" }
NR>1 {
    time = substr($1,1,11)
    totIds[time] += 0
    if ( gsub(/[][ ]/,"",$2) ) {
        totIds[time] += split($2,ids,/,/)
        for ( i in ids ) {
            unqIds[time][ids[i]]
        }
    }
}
END {
    for ( time in totIds ) {
        print time, ( type ~ /^tot/ ? totIds[time] : length(unqIds[time]) )
    }
}

$ awk -v type='tot' -f tst.awk file
20160420084:0
20160420085:26
20160420090:5

$ awk -v type='unq' -f tst.awk file
20160420084:0
20160420085:19
20160420090:5

GNU awkがない場合は、コードとメモリ使用量がわずかに増加するため、同じ操作を実行するためにawkを使用できます。

$ cat tst.awk
BEGIN { FS=OFS=":" }
NR>1 {
    time = substr($1,1,11)
    totIds[time] += 0
    if ( gsub(/[][ ]/,"",$2) ) {
        totIds[time] += split($2,ids,/,/)
        for ( i in ids ) {
            if ( !seen[time,ids[i]]++ ) {
                numUnq[time]++
            }
        }
    }
}
END {
    for ( time in totIds ) {
        print time, ( type ~ /^tot/ ? totIds[time] : numUnq[time]+0 )
    }
}

$ awk -v type='tot' -f tst.awk file
20160420084:0
20160420085:26
20160420090:5

$ awk -v type='unq' -f tst.awk file
20160420084:0
20160420085:19
20160420090:5

おすすめ記事