2009-03-04 51 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 "|"