BASH SHELL打印具有特定订单的列

时间:2016-04-01 14:49:30

标签: unix awk printing

我有这个文件:

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字或更多字的浏览器

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 }'