다음 내용을 포함하는 파일이 있습니다(첫 번째 열을 채울 추가 공백 포함).
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 주소는 쉼표로 구분되어 있으므로 이를 추가했습니다. 하지만 적어도 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