awk bash递归括号id sed tr

awk bash递归括号id sed tr,bash,awk,sed,grep,unique,Bash,Awk,Sed,Grep,Unique,服务器提供日期和冒号后用方括号中的逗号分隔的资产ID列表: 20160420084726:- 20160420085418:[111783178, 111557953, 111646835, 111413356, 111412662, 105618372, 111413557] 20160420085418:[111413432, 111633904, 111783198, 111792767, 111557948, 111413225, 111413281] 20160420085418:[1

服务器提供日期和冒号后用方括号中的逗号分隔的资产ID列表:

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]
输入日志的格式为:

timestamp:ads
其中:
timestamp
的格式为
yyymmddhhmmss
ads
是一个逗号分隔的广告资产ID列表,用方括号括起来,如果没有返回广告,则为
-

任务的第一部分是编写一个脚本,为一天中的每十分钟片段输出:

  • 返回的ID的计数
  • 返回的唯一ID的计数
  • 脚本应支持一个命令行参数,以选择应提供唯一ID还是总ID
使用上述日志摘录的输出示例(在总模式下):

在唯一计数模式下,它将给出:

20160420084:0
20160420085:19
20160420090:5
我试过这个:

awk -F '[,:]' '
                    {
                      key = substr($1,1,11)"0"
                      count[key] += ($2 == "-" ? 0 : NF-1)
                    } 
                    END {
                    PROCINFO["sorted_in"] = "@ind_num_asc"
                    for (key in count) print key, count[key]
                  }
                    ' $LOGFILENAME | grep $DATE;
使用到目前为止给出的脚本,其他场景将失败。例如,这个:

日志文件:

结果的前几行应该是:

不均匀:

20160420000:1
20160420001:11
20160420002:13
20160420003:16
20160420004:3
20160420005:3
20160420010:6
独特的:

20160420000:1
20160420001:5
20160420002:5
20160420003:5
20160420004:3
20160420005:3
20160420010:4
像这样跑:

./script.sh [-u] <input.txt
/script.sh[-u]

按摩以适应……

您尝试了什么?我看不出这个问题有任何递归性。对于其他日志文件,它不起作用,它必须对十分钟间隔内的所有事件求和。我们需要处理的是您在问题中提供的示例。如果该示例不能真正代表您的真实数据,请修复您的示例。对于其他日志文件,该示例不起作用,它必须以十分钟为间隔对所有事件求和。那么,您必须针对日志文件中存在的任何差异对其进行修改。
#!/bin/bash
while read; do
   dts=$( echo "$REPLY" | cut -d: -f1 )
   ids=$( echo "$REPLY" | grep -o '\[.*\]' )
   if [ $? -eq 0 ]; then
       ids=$( echo "$ids" | tr -d '[] ' | tr ',' '\n' | sort $1 )
       count=$( echo "$ids" | wc -l )
   else
       count=0
   fi
   echo $dts: $count
done
./script.sh [-u] <input.txt
$ cat tst.awk
BEGIN { FS="[]:[]+"; OFS=":" }
{
    tot = unq = 0
    time = substr($1,1,11)
    if ( /,/ ) {
        tot = split($2,tmp,/, ?/)
        for ( i in tmp ) {
            if ( !seen[time,tmp[i]]++ ) {
                unq++
            }
        }
    }
    tots[time] += tot
    unqs[time] += unq
}
END {
    for (time in tots) {
        print time, tots[time], unqs[time]
    }
}

$ awk -f tst.awk file
20160420084:0:0
20160420085:26:19
20160420090:5:5