2009-03-04 6 views
2

J'ai essayé:Comment puis-je grep pour un nombre de tuyaux ('|')?

grep -c "\|" *.* 

Mais il ne fonctionne pas, car il donne un nombre incorrect de tuyaux consécutifs.

Comment puis-je accomplir ceci?

+0

Voulez-vous vraiment « * . * "? Cela exclura les fichiers qui n'ont pas de point dans le nom. –

Répondre

3

Une autre l'option, en utilisant Perl, est:

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

En format non une doublure qui est:

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

La ligne while(<>){ est magique Perl pour lire les lignes des fichiers sur la commande ou de STDIN. Vous vous y habituez après un moment. La ligne elle-même va dans une variable appelée $_, qui est le paramètre par défaut pour de nombreuses commandes Perl. Par exemple tr, qui fonctionne un peu comme tr(1), fonctionne par défaut sur $_. Je mets mes résultats dans une variable globale appelée $c. (Dans un programme complet, il est préférable de déclarer une variable lexicale avec my $c = 0; en dehors de la boucle.) L'opérateur += ajoute le résultat de la commande tr (le nombre de caractères de tuyau dans ce cas) à la valeur actuelle de $c. Il est clairement plus simple d'utiliser tr(1). ;-)

L'utilisation de *.* est un DOSism que vous ne souhaitez probablement pas utiliser sur une plateforme de type UNIX. L'utilisation de guillemets simples pour éviter que le shell n'interprète le caractère de canal se lit un peu mieux. Par exemple, je l'ai testé avec ma réponse:

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

.... souhaite que je connaissais Perl. Python ne fait pas très bien les doublures. – Luis

-3

essayer

grep -c "\|" *.* 

et lire quelques tutoriels sur bash

+0

Donne un nombre incorrect s'il y a plusieurs tuyaux sur la même ligne. –

+0

Oui c'est mon problème. – Luis

+0

Je ne peux pas donner une réponse correcte à une question si vous la changez après ... – siukurnin

10

Vous pouvez utiliser tr(1) pour supprimer tous les caractères non-tube, puis utiliser wc(1) pour obtenir un total:

cat *.* | tr -d -c '|' | wc -c 
+0

Old school et très agréable. – dmckee

6

Il est contre-intuitif, mais dans la plupart regex unix, échapper à la | fait le ou opérateur. Ainsi, votre ligne correspond réellement à "rien ou rien" (vous pouvez tester cela en ajoutant des alternatives de chaque côté). Utilisez simplement

grep -c "|" *.* 

Deuxièmement, grep compte les lignes, pas les occurrences de caractères. Vous pourriez utiliser un outil différent; ou, si vous insistez sur grep, vous pouvez mettre chaque "|" sur sa propre ligne. Par exemple, avec sed:

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

Remarque: si vous utilisez sed, je conseille un beaucoup des tests pour vous assurer qu'il fait ce que vous pensez. Je devais juste alors.

Enfin, mélanger les ingrédients:

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

Malheureusement, cela pourrait ne pas fonctionner pour vous, que vous n'êtes probablement pas en utilisant unix (à cause du *.*). Mais j'espère que cela explique le problème, que je trouve toujours étrangement rassurant.

0

Si vous voulez trouver un certain nombre de tuyaux, puis

fgrep -o "|" | wc -l 

Si vous voulez trouver un certain nombre de lignes avec au moins un tuyau, puis

fgrep -c "|" 
Questions connexes