Question

I have tried:

 grep -c "\|" *.* 

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

How can I accomplish this?

Was it helpful?

Solution

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

OTHER TIPS

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

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.

If you want to find a number of pipes, then

fgrep -o "|" | wc -l

If you want to find a number of lines with at least one pipe, then

fgrep -c "|"

try

grep -c "\|" *.*

and read some tutorials about bash

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top