0

I have a file with a number of lines in a file filename.

I want to count how many lines start with character 'a', with 'b' and so on in one go.

What command i should execute.?

1
  • you want lines like "abced...", or lines beginning with an alphabet letter ? both are possible.
    – mveroone
    Aug 30, 2013 at 8:35

4 Answers 4

4

Not exactly sure I understand your question correctly, is this what you are looking for?

$ cat foo.input
afoo
abar
bfoo
bbar
bquux
cfoo

$ awk '{a[substr($0, 1, 1)]++}END{for (c in a)print c, a[c]}' foo.input
a 2
b 3
c 1

Another, simpler solution is to use colrm and uniq:

$ colrm 2 < foo.input | uniq -c
      2 a
      3 b
      1 c
2
  • colrm is a need-to-remember command... but I gave you already my +1 ;)
    – mpy
    Aug 30, 2013 at 9:21
  • @mpy I agree, and to be honest, I think this is the first time I have actually used it usefully since I never remember it ... ;-) Aug 30, 2013 at 9:23
2

This is a perfect job for uniq:

uniq -c -w 1 filename

-w 1 compares only the the first character of each line; -c counts the occurrences.

With foo.input from Adrian's answer you get (don't be confused about afoo, bfoo etc.; these are simply the first lines which start with a, b, etc.)

    2 afoo
    3 bfoo
    1 cfoo

Pipe the result through sort -n, if you want it sorted by the number of occurrences:

$ uniq -c -w 1 foo.input | sort -n
    1 cfoo
    2 afoo
    3 bfoo
4
  • Much much simplier than my solution, except it will handle Uppercase separatly.
    – mveroone
    Aug 30, 2013 at 9:08
  • I wanted to post this first, but the output is a bit unlucky without further processing. Aug 30, 2013 at 9:12
  • @AdrianFrühwirth: You are right, I was confused for a moment myself and therefore added a note in the text. But IMHO it answers the question fine as this command counts correctly.
    – mpy
    Aug 30, 2013 at 9:15
  • I agree, your answer is perfectly valid, so +1 (see my edit for a uniq solution that gets rid of the confusing output). Aug 30, 2013 at 9:17
1

Or, if you're more into use of perl and grep:

perl -le '$, = "\n"; print ("a".."z")' | xargs -i grep -c '^{}' foo.input
1

Another solution, because sometimes it's easier to remember small blocks and assemble them :

$ cat foo.input
afoo
abar
bfoo
bbar
bquux
cfoo

$ cat foo.input | cut -c 1 | tr '[[:upper:]]' '[[:lower:]]' | sort | grep '^[a-z]'| uniq -c
      2 a
      3 b
      1 c

Explanation of the one-liner :

  • cat read the file
  • cut -c 1 trims everything but the first character of each line
  • tr '[[:upper:]]' '[[:lower:]]' replaces uppercase to lowercase
  • sort ... sorts the lines
  • grep '^[a-z]' remove lines not beginning with a letter
  • uniq -c counts identical lines
3
  • 1
    You could use cut -c 1 foo.input instead of cat foo.input | cut -c 1...
    – Tim
    Aug 30, 2013 at 9:20
  • Actually I was doing cut -c 1 <foo.input but that messed up with the <pre> formatting. Your alternative works indeed.
    – mveroone
    Aug 30, 2013 at 9:21
  • You might want to use [[:upper:]]/[[:lower:]], just in case. Aug 30, 2013 at 9:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .