[comp.lang.perl] Counting characters with unix utilities

emv@math.lsa.umich.edu (Edward Vielmetti) (09/24/90)

In article <4002@umbc3.UMBC.EDU> rouben@math9.math.umbc.edu writes:

   How can I count the number of occurrences of a given character in a file?
   It can be done rather trivially in C, but I wonder if it can also be done
   using standard unix utilities like awk, sed, tr, wc, etc.

   The closest  I have come to this is the following construction:

   cat file | tr -c 'A' '' | wc -c

This is what I came up with in perl, after about 15 minutes of digging
in the perl info pages:

   cat file | perl -ne '$c += tr/A/A/; if (eof()) {print "$c\n";}'

Going back to the tr man page this one seems to work too:

   cat file | tr -cd 'A' | wc -c

I don't see an easy perl equivalent of the "tr -cd" idiom.

--Ed

Edward Vielmetti, U of Michigan math dept <emv@math.lsa.umich.edu>
moderator, comp.archives

merlyn@iwarp.intel.com (Randal Schwartz) (09/24/90)

In article <EMV.90Sep23181658@picasso.math.lsa.umich.edu>, emv@math (Edward Vielmetti) writes:
| Going back to the tr man page this one seems to work too:
| 
|    cat file | tr -cd 'A' | wc -c
| 
| I don't see an easy perl equivalent of the "tr -cd" idiom.

You *will* in Perl 4.0 (coming real soon).  Perl is being upgraded
with a few new features so that it matches the new specification ("The
Book").

The 'tr' operator gets a few new options, namely 'c', 'd', and 's',
acting just like their tr(1) cousins.

By the way, you don't need all those 'cat file' things.  Just go:

perl -ne '$c += tr/A/A/; print $c if eof;' file

One process fits all.

print "Just another Perl [book] hacker,"
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/

ted@nmsu.edu (Ted Dunning) (09/24/90)

i didn't want to answer this one, but

In article <EMV.90Sep23181658@picasso.math.lsa.umich.edu> emv@math.lsa.umich.edu (Edward Vielmetti) writes:

   In article <4002@umbc3.UMBC.EDU> rouben@math9.math.umbc.edu writes:

	...
      cat file | tr -c 'A' '' | wc -c

	...

   ...
   cat file | tr -cd 'A' | wc -c



ed must have been kidding when he left the cat in place, instead of

tr -cd 'A' < file | wc -c

--
ted@nmsu.edu					+---------+
						| In this |
						|  style  |
						|__10/6___|

aks@hub.ucsb.edu (Alan Stebbens) (09/25/90)

In article <4002@umbc3.UMBC.EDU> rouben@math9.math.umbc.edu writes:

rouben> How can I count the number of occurrences of a given character
rouben> in a file?  It can be done rather trivially in C, but I wonder
rouben> if it can also be done using standard unix utilities like awk,
rouben> sed, tr, wc, etc.
rouben> The closest  I have come to this is the following construction:
rouben> cat file | tr -c 'A' '' | wc -c

ed> Going back to the tr man page this one seems to work too:
ed>    cat file | tr -cd 'A' | wc -c
ed> I don't see an easy perl equivalent of the "tr -cd" idiom.

Try:
	perl -ne '$s+=tr/A//;if(eof){print $s,"\n";}' file

worley@compass.com (Dale Worley) (09/25/90)

   X-Name: Randal Schwartz

   perl -ne '$c += tr/A/A/; print $c if eof;' file

Doesn't this fail if the file is empty?

Dale Worley		Compass, Inc.			worley@compass.com
--
Using MS-DOS on a '386 is like using a Formula 1 race car to do your
grocery shopping.

merlyn@iwarp.intel.com (Randal Schwartz) (09/26/90)

In article <1990Sep25.151014.11935@uvaarpa.Virginia.EDU>, worley@compass (Dale Worley) writes:
| 
|    X-Name: Randal Schwartz
| 
|    perl -ne '$c += tr/A/A/; print $c if eof;' file
| 
| Doesn't this fail if the file is empty?

Ooops.  I'll be out painting fence-posts for a while, sorry. :-)
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/

worley@compass.com (Dale Worley) (09/26/90)

   From: merlyn@iwarp.intel.com (Randal Schwartz)

   |    perl -ne '$c += tr/A/A/; print $c if eof;' file
   | 
   | Doesn't this fail if the file is empty?

   Ooops.  I'll be out painting fence-posts for a while, sorry. :-)

It seems like it would be useful to be able to prescribe prolog and
epilog code for -n (and -p) loops.  AWK does this with BEGIN and END.
Then it would be simple:

	perl -ne '$c += tr/A/A/' -xxx 'print $c' file

Dale Worley		Compass, Inc.			worley@compass.com
--
Give yourself over to absolute pleasure
Swim the warm waters of sins of the flesh
Erotic madness beyond any measure
And sensual daydreams to treasure... forever.
-- Rocky Horror Picture Show

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (09/27/90)

In article <1990Sep26.125033.19669@uvaarpa.Virginia.EDU> worley@compass.com writes:
: 
:    From: merlyn@iwarp.intel.com (Randal Schwartz)
: 
:    |    perl -ne '$c += tr/A/A/; print $c if eof;' file
:    | 
:    | Doesn't this fail if the file is empty?
: 
:    Ooops.  I'll be out painting fence-posts for a while, sorry. :-)
: 
: It seems like it would be useful to be able to prescribe prolog and
: epilog code for -n (and -p) loops.  AWK does this with BEGIN and END.
: Then it would be simple:
: 
: 	perl -ne '$c += tr/A/A/' -xxx 'print $c' file

It hardly seems worth it to add a new switch when you can say

	perl -e 'while(<>){$c += tr/A/A/;}print $c' file

or

	perl -ne '$c += tr/A/A/; print $c if eof()' file

or

	perl -e 'undef $/; $_ = <>; print tr/A/A/' file

or even

	perl -e '$c += tr/A/A/ while <>; print $c' file

Although the Perl Slogan is There's More Than One Way to Do It, I hesitate
to make 10 ways to do something.  :-)

Larry