Grep for multiple patterns in a file

2019-09-11 23:22发布

I'd like to count number of xml nodes in my xml file(grep or somehow).

....
<countryCode>GBR</countryCode>
<countryCode>USA</countryCode>
<countryCode>CAN</countryCode>
...
<countryCode>CAN</countryCode>
<someNode>USA</someNode>
<countryCode>CAN</countryCode>
<someNode>Otherone</someNode>
<countryCode>GBR</countryCode>
...

How to get count of individual countries like CAN = 3, USA = 1, GBR = 2? Without passing in the names of the countries there might be some more countries?

Update:

There are other nodes beside countrycode

标签: linux shell unix
8条回答
虎瘦雄心在
2楼-- · 2019-09-12 00:07
sed -n "s/<countryCode>\(.*\)<\/countryCode>/\1/p"|sort|uniq -c
查看更多
霸刀☆藐视天下
3楼-- · 2019-09-12 00:07

Quick and simple:

grep countryCode ./file.xml | sort | uniq -c

查看更多
▲ chillily
4楼-- · 2019-09-12 00:08
cat dummy | sort |cut -c14-16 | sort |tail -6 |awk  '{col[$1]++} END {for (i in col) print i, col[i]}'

Dummy is ur file name and replace 6 in -6 with n-2(n - no of lines in ur data file)

查看更多
虎瘦雄心在
5楼-- · 2019-09-12 00:15

quick and dirty (only based on your example text):

awk -F'>|<' '{a[$3]++;}END{for(x in a)print x,a[x]}' file

test:

kent$  cat t.txt
<countryCode>GBR</countryCode>
<countryCode>USA</countryCode>
<countryCode>CAN</countryCode>
<countryCode>CAN</countryCode>
<countryCode>CAN</countryCode>
<countryCode>GBR</countryCode>

kent$  awk -F'>|<' '{a[$3]++;}END{for(x in a)print x,a[x]}' t.txt 
USA 1
GBR 2
CAN 3
查看更多
beautiful°
6楼-- · 2019-09-12 00:18

My simple suggestion would be to use sort and uniq -c

$ echo '<countryCode>GBR</countryCode>
<countryCode>USA</countryCode>
<countryCode>CAN</countryCode>
<countryCode>CAN</countryCode>
<countryCode>CAN</countryCode>
<countryCode>GBR</countryCode>' | sort | uniq -c
      3 <countryCode>CAN</countryCode>
      2 <countryCode>GBR</countryCode>
      1 <countryCode>USA</countryCode>

Where you'd pipe in the output of your grep instead of an echo. A more robust solution would be to use XPath. If youre XML file looks like

<countries>
  <countryCode>GBR</countryCode>
  <countryCode>USA</countryCode>
  <countryCode>CAN</countryCode>
  <countryCode>CAN</countryCode>
  <countryCode>CAN</countryCode>
  <countryCode>GBR</countryCode>
</countries>

Then you could use:

$ xpath -q -e '/countries/countryCode/text()'  countries.xml  | sort | uniq -c
      3 CAN
      2 GBR
      1 USA

I say it's more robust because using tools designed for parsing flat text will be inherently flaky for dealing with XML. Depending on the context of the original XML file, a different XPath query might work better, which would match them anywhere:

$ xpath -q -e '//countryCode/text()'  countries.xml  | sort | uniq -c
      3 CAN
      2 GBR
      1 USA
查看更多
狗以群分
7楼-- · 2019-09-12 00:18

Something like this maybe:

grep -e 'regex' file.xml | sort | uniq -c

Of course you need to provide regex that matches your needs.

查看更多
登录 后发表回答