> cat logfile | awk '/ERROR:/ {counts[$1] = counts[$1] + 1}; END { for (day in counts) print day " : " counts[day]}' | sort
Great first program! a bit less verbose could be
> awk '/ERROR:/ {counts[$1]++}END{...}' logfile
there are also ways of sorting the output but within (g)awk (asort & asorti) but sorting externally as you have is more flexible and engages another core which can be faster on large input
grep ERROR logfile | cut -f 1 -d ' ' | sort | uniq -c
It's not detrimental to performance since an empty cat is a no-op in a pipeline. You can have any number of them. But commands should be written for humans to understand, and inserting no-ops is a distraction to the reader.
In the trivial example, "grep needle haystack" reads better than "cat haystack | grep needle".
EDIT: I'm not sure if it's actually correct however...