Encontre o valor da diferença entre o maior e o menor tempo da mesma variável?

2

Eu tenho o arquivo fb.csv como abaixo.

"Source","Time"  
"192.168.137.174","12:26:25"
"10.0.138.163","12:26:25"
"157.240.10.13","12:26:36"
"157.240.10.13","12:26:36"
"157.240.10.23","12:26:41"
"157.240.10.23","12:26:41"
"10.0.138.163","12:26:52"
"192.168.137.174","12:26:52"
"157.240.10.18","12:26:52"
"157.240.10.18","12:26:52"
"157.240.10.23","12:26:53"
"157.240.10.23","12:26:53"
"192.168.137.174","12:27:02"
"10.0.138.163","12:27:02"
"192.168.137.174","12:27:07"

Eu gostaria de encontrar o valor da diferença entre o maior tempo e o menor tempo para a mesma "fonte".

Saída desejada;

"Source","Duration Time"  
"192.168.137.174","00:01:22"
"10.0.138.163","00:01:17"
"157.240.10.13","00:00:00"
"157.240.10.23","00:00:00"
"157.240.10.18","00:00:00"

Existe algum método para isso? Obrigado

    
por Ayu 14.09.2017 / 21:09

1 resposta

2

Sou eu novamente, o cara com os enormes comandos awk de uma linha ... Esse é ainda mais longo:

awk -F, 'BEGIN{print"\"Source\",\"Duration Time\""}NR>1{gsub(/"/,"",);split(,hms,":");s=hms[1]*3600+hms[2]*60+hms[3];if(!((,"MAX")in a)||a[,"MAX"]<s)a[,"MAX"]=s;if(!((,"MIN")in a)||a[,"MIN"]>s)a[,"MIN"]=s}END{for(idx in a){split(idx,ipm,SUBSEP);if(ipm[2]=="MAX"){d=a[idx]-a[ipm[1],"MIN"];h=int(d/3600);m=int((d-h*3600)/60);s=d%60;printf("%s,\"%02d:%02d:%02d\"\n",ipm[1],h,m,s)}}}' fb.csv 

Com seu arquivo de entrada fb.csv da pergunta, a saída é assim:

"Source","Duration Time"
"157.240.10.23","00:00:12"
"157.240.10.18","00:00:00"
"157.240.10.13","00:00:00"
"10.0.138.163","00:00:37"
"192.168.137.174","00:00:42"

Explicação do comando:

Corremos awk assim, definindo o separador de campos que delimita as colunas para , e usando o arquivo fb.csv como entrada:

awk -F, '<COMMAND>' fb.csv

O comando awk (espaço reservado <COMMAND> acima) é este, após a formatação adequada:

BEGIN {
    print "\"Source\",\"Duration Time\""
}
NR>1 {
    gsub(/"/, "", )
    split(, hms, ":")
    s = hms[1]*3600 + hms[2]*60 + hms[3]
    if ( !((,"MAX") in a) || a[,"MAX"] < s )
        a[,"MAX"] = s
    if ( !((,"MIN") in a) || a[,"MIN"] > s )
        a[,"MIN"] = s
}
END {
    for (idx in a) {
        split(idx, ipm, SUBSEP)
        if (ipm[2]=="MAX") {
            d = a[idx] - a[ipm[1],"MIN"]
            h = int(d / 3600)
            m = int((d - h * 3600) / 60)
            s = d%60
            printf("%s,\"%02d:%02d:%02d\"\n", ipm[1] ,h ,m ,s)
        }
    }
}
  • O bloco BEGIN simplesmente imprime o novo cabeçalho CSV.

  • O bloco NR>1 é executado uma vez por linha no arquivo de entrada, exceto pela primeira linha que contém o cabeçalho. Cada linha é dividida na coluna IP ( ) e na coluna de hora ( ).

    Nós processamos a coluna de tempo retirando as cotas com gsub e dividindo-as nos dois pontos em uma matriz hms que contém as horas, minutos e segundos. Isso é usado para converter o registro de data e hora em segundos desde a meia-noite, armazenado em s neste bloco.

    Em seguida, verificamos a matriz associativa se ainda não houver uma entrada com o IP da linha atual ou se a entrada tiver valores menores de tempo MÍNIMO ou maiores, e, nesse caso, ela será atualizada de acordo.

  • Finalmente, no bloco END , a matriz criada é avaliada e para cada IP nela, a diferença entre as marcações de hora MAX e MIN é calculada e salva como d . Isso é convertido novamente em horas, minutos e segundos e é exibido corretamente formatado.

por Byte Commander 15.09.2017 / 12:46