I have tried:
grep -c "\|" *.*
But it didn't work, since it gives an incorrect count of consecutive pipes.
How can I accomplish this?
I have tried:
grep -c "\|" *.*
But it didn't work, since it gives an incorrect count of consecutive pipes.
How can I accomplish this?
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
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
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.