我有一个包含以下内容的文件(还有额外的空格来填充第一列)
1 account1 192.168.0.1
1 account1 192.168.0.2
19 account2 192.168.0.1
100 account3 192.168.0.3
1 account3 192.168.0.5
我正在尝试获得以下输出
2 account1 192.168.0.1, 192.168.0.2
19 account2 192.168.0.1
101 account3 192.168.0.3, 192.168.0.5
我将循环遍历它,以便我可以创建一个 html 表以通过电子邮件发送到帐户。我设法使用以下命令获取每个帐户的 IP 列表:
awk '{a[$2]=a[$2]" " $3}END{for (i in a) print i" " a[i]}' inputfile
但我也无法对第一列求和。
答案1
将总和添加到脚本中应该不太难,只需添加另一个数组来保存它即可。
$ awk '{ if (a[$2]) a[$2] = a[$2] ", ";
a[$2] = a[$2] $3;
sum[$2] += $1 }
END {for (x in a) printf "%3d %s %s\n", sum[x], x, a[x]}' inputfile
2 account1 192.168.0.1, 192.168.0.2
19 account2 192.168.0.1
101 account3 192.168.0.3, 192.168.0.5
(您的示例输出中的 IP 地址以逗号分隔,因此我也添加了该地址。但在我看来,如果没有它,至少代码会更整洁。)
答案2
Awk
解决方案:
awk 'NR==1{ match($0, /^ +[^ ]+/); s=length(substr($0, RSTART, RLENGTH)) }
{ sum[$2]+=$1; ips[$2]=($2 in ips? ips[$2]", ":"")$3 }
END{
for (i in sum)
printf("%*s %s %s\n", s, sum[i], i, ips[i])
}' file
输出:
2 account1 192.168.0.1, 192.168.0.2
19 account2 192.168.0.1
101 account3 192.168.0.3, 192.168.0.5
答案3
我可能想得太多了,(可能有一个很好的 awk/sed 可以使用)但这是我能想到的最好的事情:
#!/bin/bash
# set file as sys argument
file=$1
# pull unique account names into an array
account_names=($(awk '{print $2}' $file | sort | uniq))
# loop through and store column values
for account in ${account_names[@]}; do
# get a sum of the first column
col1=$(grep $account $file | awk '{SUM += $1} END {print SUM}')
# get last column and convert to one line with comma separation
IP_list=$(grep $account $file | awk '{print $NF}' | sort | uniq | tr '\n' ',' | sed s'/.$//')
# print them together
echo "$col1 $account $IP_list"
done
然后你可以像这样运行它:
┌─[robotjohny@Fedora]─[~]─[04:08 pm]
└─[$]› ./test1.sh file1.txt
2 account1 192.168.0.1,192.168.0.2
19 account2 192.168.0.1
101 account3 192.168.0.3,192.168.0.5