2009-03-04 25 views
2

我曾尝试:我怎么能grep的管道数('|')?

grep -c "\|" *.* 

但它没有工作,因为它提供了连续管的不正确计数。

我该如何做到这一点?

+0

你真的想“* 。*“?这将排除名称中没有点的文件。 – 2009-03-05 13:12:17

回答

3

另一个选项,使用Perl,是:

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

在非一个班轮格式是:

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

while(<>){行是Perl的魔力来自于命令或STDIN文件中读取行。你过一会儿就习惯了。该行本身进入一个名为$_的变量,该变量是许多Perl命令的默认参数。例如tr,其工作方式与tr(1)相似,默认为在$_上运行。我将我的结果放入一个名为$c的全局变量中。 (在完整程序中,最好将其声明为循环外部的my $c = 0;的词法变量。)+=运算符将tr命令的结果(此例中为管道字符数)与当前值$c相加。

只要使用tr(1)显然是一个更简单的选项。 ;-)

使用*.*是DOSism,您不希望在类UNIX平台上使用DOSism。

使用单引号避免让shell解释管道字符的读取好一点。举例来说,我测试了我的答案是:

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

尝试

grep -c "\|" *.* 

和阅读有关bash的一些教程

+0

如果同一行上有多个管道,将会给出错误的计数。 – 2009-03-04 22:13:53

+0

是的,这是我的问题。 – Luis 2009-03-04 22:14:45

+0

如果您之后改变了这个问题,我无法给出正确的答案... – siukurnin 2009-03-06 11:21:14

10

您可以使用tr(1)删除所有非管道字符,然后用wc(1)一共拿到:

cat *.* | tr -d -c '|' | wc -c 
6

这是违反直觉的,但在大多数UNIX正则表达式,逃避|使得它或运营商。所以你的线路实际上是匹配“什么也没有”(你可以通过在任何一边添加一些替代品来测试这一点)。只需使用

grep -c "|" *.* 

其次,grep对行进行计数,而不是字符出现次数。你可以使用不同的工具;或者,如果你坚持grep,你可以把每个“|”在自己的路线上。例如,对于SED:

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

注意:如果使用SED,我劝测试的很多以确保它做什么,你认为它。我需要那时。

最后,结合成份:

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

不幸的是,这可能不是为你工作,因为你很可能不使用UNIX(因为*.*的)。但希望能解释这个问题,我总觉得这个问题令人奇怪地让人放心。

0

如果你想找到一些管道,然后

fgrep -o "|" | wc -l 

如果你想找到一些与至少一个管道线,然后

fgrep -c "|"