【问题标题】:Unix shell - manipulation and filtering of textUnix shell - 文本的操作和过滤
【发布时间】:2018-11-22 16:59:36
【问题描述】:
我正在尝试使用 Unix shell 解决任务。我有以下输出:
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 acceptedAttempts。
有人对我如何解决这个问题有任何意见吗?
【问题讨论】:
标签:
shell
unix
filter
terminal
【解决方案1】:
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;
'
【解决方案2】:
这可以通过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
【解决方案3】:
我添加了一个 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
【解决方案4】:
以下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