我试过了:
grep -c "\|" *.*
但它不起作用,因为它给出了不正确的连续管道计数。
我怎样才能做到这一点?
您可以使用tr(1)
删除所有非管道字符,然后使用wc(1)
获取总数:
cat *.* | tr -d -c '|' | wc -c
这是违反直觉的,但在大多数 unix 正则表达式中,转义 the|
使其成为或运算符。因此,您的行实际上与“无或无”匹配(您可以通过在任一侧添加一些替代方案来测试这一点)。只需使用
grep -c "|" *.*
其次,grep 计算行数,而不是字符出现次数。您可以使用不同的工具;或者,如果您坚持使用 grep,则可以将每个“|” 在自己的线上。例如,使用 sed:
sed 's/|/|\n/g' *.*
注意:如果使用 sed,我建议进行大量测试以确保它按照您的想法执行。我当时需要。
最后,结合成分:
cat *.* | sed 's/|/|\n/g' | grep -c "|"
不幸的是,这可能对您不起作用,因为您可能没有使用 unix(因为*.*
. 但希望它能解释这个问题,我总是觉得奇怪的是让人放心。
另一个使用 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)
显然是一个更简单的选择。;-)
Using*.*
是一种 DOSism,您可能不想在类 UNIX 平台上使用它。
使用单引号来避免 shell 解释管道字符会更好一些。例如,我测试了我的答案:
$ echo '||||
|||||' | perl -e 'while(<>){$c+=tr/|/|/};print "$c\n"'
9
如果要查找多个管道,则
fgrep -o "|" | wc -l
如果你想找到至少有一个管道的多条线,那么
fgrep -c "|"
尝试
grep -c "\|" *.*
并阅读一些关于 bash 的教程