tags:

views:

497

answers:

4

I have tried:

 grep -c "\|" *.*

But it didn't work, since it gives an incorrect count of consecutive pipes.

How can I accomplish this?

A: 

try

grep -c "\|" *.*

and read some tutorials about bash

siukurnin
Will give incorrect count if there are multiple pipes on the same line.
Nick Presta
Yes this is my problem.
Luis
I can't give a correct answer to a question if you change it afterwards ...
siukurnin
+8  A: 

You can use tr(1) to delete all non-pipe characters and then use wc(1) to get a total:

cat *.* | tr -d -c '|' | wc -c
Adam Rosenfield
Old school and very nice.
dmckee
+3  A: 

Another option, using Perl, is:

perl -e 'while(<>){$c+=tr/|/|/};print "$c\n"' *

In non-one-liner format that's:

while(<>){
    $c += tr/|/|/
}
print "$c\n"

The while(<>){ line is Perl magic for reading lines from files on the command or from STDIN. You get used to it after a while. The line itself goes into a variable called $_, which is the default parameter for many Perl commands. For instance tr, which works quite a bit like tr(1), defaults to operating on $_. I'm putting my results in a global variable called $c. (In a full program, it's best to declare it a lexical variable with my $c = 0; outside the loop.) The += operator adds the result of the tr command (the number of pipe characters in this case) to the current value of $c.

Just using tr(1) is clearly a simpler option. ;-)

Using *.* is a DOSism that you don't likely want to use on a UNIX-like platform.

Using single quotes to avoid having the shell interpret the pipe character reads a bit better. For instance, I tested my answer with:

$ echo '||||
|||||' | perl -e 'while(<>){$c+=tr/|/|/};print "$c\n"'
9
Jon Ericson
.... wish I knew Perl. Python doesn't do one-liners very well.
Luis
+2  A: 

It's counterintuitive, but in most unix regex, escaping the | makes it the or-operator. So your line is actually matching "nothing or nothing" (you can test this out by add some alternatives on either side). Just use

grep -c "|" *.*

Secondly, grep counts lines, not character occurrences. You could use a different tool; or, if you insist on grep, you could put each "|" on its own line. For example, with sed:

sed 's/|/|\n/g' *.*

Note: if using sed, I advise a lot of testing to make sure it does what you think it does. I needed to just then.

Finally, combine the ingredients:

cat *.*  |  sed 's/|/|\n/g'  |  grep -c "|"

Unfortunately this might not work for you, as you're probably not using unix (because of the *.*). But hopefully it explains the problem, which I always find strangely reassuring.

13ren