Unix shell - манипулирование и фильтрация текста - PullRequest
0 голосов
/ 22 ноября 2018

Я пытаюсь решить задачу с помощью оболочки Unix.У меня есть следующий вывод:

  2 Accepted 10.0.0.202
  8 Failed 10.0.0.202
 11 Failed 10.0.0.202
  1 Accepted 151.62.163.222
  3 Failed 151.62.163.222

Я хочу выяснить для каждого из IP-адресов, сколько было неудачных и сколько принято, и напечатать это так: IP-adr failedAttempts acceptAttempts.

У кого-нибудь есть информация о том, как я могу решить эту проблему?

Ответы [ 4 ]

0 голосов
/ 22 ноября 2018

Это можно сделать довольно элегантно с помощью GNU Datamash 1.3 и его операции crosstab / pivot :

$ datamash -W crosstab 3,2 sum 1 < data
        Accepted        Failed
10.0.0.202      2       19
151.62.163.222  1       3
0 голосов
/ 22 ноября 2018

Следующий скрипт AWK может быть использован для выполнения задачи.Сохраните скрипт в файле и затем выполните команду bash: $ awk -f scipt_file text_file.

{
    if ($2 == "Failed") {
        if ($3 in failed)
            failed[$3] += $1
        else 
            failed[$3] = $1
    }

    else {
        if ($3 in accepted)
            accepted[$3] += $1
        else
            accepted[$3] = $1
    }
}

END {
    printf "%-16s\t%s\t%s\n", "IP", "Failed", "Accepted"
    for (ip in accepted) {
        if (ip in failed) {
            nfail = failed[ip] 
        } else 
            nfail = 0
        printf "%-16s\t%d\t%d\n", ip, nfail, accepted[ip]
    }

    for (ip in failed) {
        if (ip in accepted) {} 
        else {
            printf "%-16s\t%d\t%d\n", ip, failed[ip], 0 
        } 
    }
}

. Она печатает:

IP                      Failed  Accepted
151.62.163.222          3       1
10.0.0.202              19      2
0 голосов
/ 22 ноября 2018

GNU awk имеет массив массивов, так что это довольно просто:

processToProduceOutput | gawk '
    {count[$3][$2] += $1} 
    END {
        for (ip in count)
            print ip, 0 + count[ip]["Accepted"], 0 + count[ip]["Failed"]
    }
'

, который производит

151.62.163.222 1 3
10.0.0.202 2 19

Чтобы сделать вывод более красивым, направьте в | column -t

0 + count... позволит IP-адресу без принятого / неудачного показа 0 в соответствующем столбце.


Есть также этот слишком умный perl

perl -lane '
    $c{$F[2]}{$F[1]} += $F[0];
}{ 
    printf "%s %d %d\n", $_, map {0+$_} $c{$_}->@{"Accepted","Failed"} for keys %c;
'
0 голосов
/ 22 ноября 2018

Я добавил ip для тестирования пограничного случая:

(pi 695) $ cat /tmp/x 
 2 Accepted 10.0.0.202
  8 Failed 10.0.0.202
 11 Failed 10.0.0.202
  1 Accepted 151.62.163.222
  3 Failed 151.62.163.222
111 Failed 8.8.8.8
222 Failed 8.8.8.8
(pi 696) $ awk '
  {ip[$3]++}                  # keep track of ALL ip addresses
  $2=="Accepted" {a[$3]+=$1}  # keep track of all Accepted
  $2=="Failed"   {f[$3]+=$1}  # keep track of all Failed
  END{
    for(i in ip){             # for every ip seen
      print i, f[i]+0, a[i]+0 # print ip, failures, and accepts
    }
  }' /tmp/x
151.62.163.222 3 1
8.8.8.8 333 0
10.0.0.202 19 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...