日常部分數據以 txt 的文件格式提供,為避免入庫之后再進行統計的麻煩,故學習 shell 進行處理,減少工作量。
1.樣例數據
# test.txt
YD5Gxxx|6618151|6825449073|6476534190|36251|超級會員|0
YD5Gxxx|8968336|1445546463|6476534190|36251|超級會員|0
YD5Gxxx|2545939|6904742993|0858636804|36251|超級會員|80%以上
YD5Gxxx|3200810|6896525523|6501574903|36251|普通|0
YD5Gxxx|3378244|6926264463|6519442719|36251|超級會員|80%以上
YD5Gxxx|8075700|6854827783|0858523344|36251|普通|80%以上
YD5Gxxx|3368804|6934387193|0000487348|36251|超級會員|(0,50%]
YD5Gxxx|2865288|6865082233|0859114957|36251|普通|(0,50%]
YD5Gxxx|6655543|6930124273|6521876215|36251|超級會員|(0,50%]
YD5Gxxx|2952781|6820973583|0858704189|36251|超級會員|0
2.一些普通操作
通過 awk -F
可以實現按分隔符進行切割操作,再通過 {print $6}
可以輸出字段。
sort
進行排序,uniq
進行去重操作,wc -l
進行計數操作。
cat test.txt | awk -F '|' '{print $6}' | sort
普通
普通
普通
超級會員
超級會員
超級會員
超級會員
超級會員
超級會員
超級會員
cat test.txt | awk -F '|' '{print $6}' | sort | uniq
普通
超級會員
cat test.txt | awk -F '|' '{print $6}' | sort | uniq | wc -l
2
也可以通過 grep
進行查找,然后再進行下一步操作,例如重定向到另一個新的文件。
cat test.txt | grep '超級會員' | awk -F '|' '{print $2}' > super_user.txt
通過 split -l
對文件進行切分。
split -l 5 super_user.txt
# 每5行切分為一個文件
3.分組統計
[$6]
實現分組,count[$6]++
實現計數。
awk -F '|' '{count[$6]++;} END {for(i in count) {print i count[i]}}' test.txt
普通3
超級會員7
根據第7列進行篩選之后,再按第6列進行分組統計。
awk -F '|' '{if($7=="0") {count[$6]++;}} END {for(i in count) {print i count[i]}}' test.txt
普通1
超級會員3
4.分組求和
對所有進行求和。
awk -F '|' '{sum += $2} END {print sum}' test.txt
# 48629596
分組一般使用x[$2]=x[$3]的方式來實現,其中x[$2]中的$2為要分的組,可以多個分組,x[$3]為要處理的值。
一次分組
awk -F '|' '{x[$6] += $2} END {for(i in x){print i, x[i]}}' test.txt
普通 14141798
超級會員 34487798
二次分組
awk -F '|' '{x[$6"-"$7] += $2} END {for(i in x){print i, x[i]}}' test.txt
超級會員-80%以上 5924183
超級會員-0 18539268
普通-(0,50%] 2865288
超級會員-(0,50%] 10024347
普通-0 3200810
普通-80%以上 8075700
格式化處理
awk -F '|' '{x[$6] += $2} END {for(i in x){print("%s\t%d\n",i,x[i])}}' test.txt
# 顯示的格式有點不對勁
分組求平均值
awk -F '|' '{sum += $2} END {print "Average = ", sum/NR}' test.txt
# Average = 4.86296e+06
awk -F '|' '{a[$6] += $2; ca[$6]++} END {for(i in a){print(i,a[i]/ca[i])}}' test.txt
# 普通 4.71393e+06
# 超級會員 4.92683e+06
分組求最大最小
awk -F '|' 'BEGIN {max=0} {if($2>max){max=$2}} END {print max}' test.txt
# 最大值
awk -F '|' '{if($2>x[$6]){x[$6]=$2}} END {for(i in x) {print i, x[i]}}' test.txt
# 普通 8075700
# 超級會員 8968336
分組整理字符
awk -F '|' '{x[$6]=x[$6]"\n"$2} END {for(i in x){print i ":" x[i]}}' test.txt
普通:
3200810
8075700
2865288
超級會員:
6618151
8968336
2545939
3378244
3368804
6655543
2952781