我有这个文件:
933|Mahinda|Perera|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox
1129|Carmen|Lepland|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer
4194|Hồ ChÃ|Do|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer
8333|Chen|Wang|female|1980-02-02|2010-03-15T10:21:43.365+0000|1.4.16.148|Internet Explorer
8698|Chen|Liu|female|1982-05-29|2010-02-21T08:44:41.479+0000|14.103.81.196|Firefox
8853|Albin|Monteno|male|1986-04-09|2010-03-19T21:52:36.860+0000|178.209.14.40|Internet Explorer
10027|Ning|Chen|female|1982-12-08|2010-02-22T17:59:59.221+0000|1.2.9.86|Firefox
和这个订单
./tool.sh --browsers -f <file>
我想按特定顺序计算浏览器的数量,例如:
Chrome 143
Firefox 251
Internet Explorer 67
我使用这个命令:
if [ "$1" == "--browsers" -a "$2" == "-f" -a "$4" == "" ]
then
awk -F'|' '{print $8}' $3 | sort | uniq -c | awk ' {print $2 , $3 , $1} '
fi
但它仅适用于3个参数。如何让它适用于许多论点?例如一个4字或更多字的浏览器
答案 0 :(得分:1)
看起来像是计算浏览器的awk单行程序:
$ awk -F'|' '{a[$8]++} END{for(i in a){printf("%s %d\n",i,a[i])}}' inputfile
Firefox 3
Internet Explorer 4
这会增加数组的元素,然后在文件末尾逐步执行数组并打印总数。如果要对输出进行排序,可以通过sort
进行管道输出。我没有看到浏览器名称中有多个单词的问题。
答案 1 :(得分:0)
试试这个:
awk -F"|" '{print $8}' in | sort | uniq -c | awk '{print $2,$1}'
其中in
是输入文件。
输出
[myShell] ➤ awk -F"|" '{print $8}' in | sort | uniq -c | awk '{print $2,$1}'
Firefox 3
Internet 4
对于解析参数也最好使用getopts
即
#!/bin/bash
function usage {
echo "usage: ..."
}
while getopts b:o:h opt; do
case $opt in
b)
fileName=$OPTARG
echo "filename[$fileName]"
awk -F"|" '{print $8}' $fileName | sort | uniq -c | awk '{print $2,$1}'
;;
o)
otherargs=$OPTARG
echo "otherargs[$otherargs]"
;;
h)
usage && exit 0
;;
?)
usage && exit 2
;;
esac
done
输出
[myShell] ➤ ./arg -b in
filename[in]
Firefox 3
Internet 4
答案 2 :(得分:0)
你的最终Awk硬编码两个字段;只需继续$4, $5, $6
等即可打印更多字段。但是,这会为每个逗号添加一个虚假空间。
更好的是,由于第一个字段是固定宽度(因为它是uniq -c
的输出格式),您可以print substr($0,8), $1
答案 3 :(得分:-1)
我在perl中做到了:
#!/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %count_of;
while ( <> ) {
chomp;
$count_of{(split /\|/)[7]}++;
}
print Dumper \%count_of;
这可以减少到一个班轮:
perl -F'\|' -lane '$c{$F[7]++}; END{ print "$_ => $c{$_}" for keys %c }'