2009-03-04 3 views
2

Ich habe versucht:Wie kann ich nach einer Anzahl von Pipes grep ('|')?

grep -c "\|" *.* 

Aber es hat nicht funktioniert, weil es eine falsche Zählung von aufeinanderfolgenden Rohren gibt.

Wie kann ich das erreichen?

+0

Wollen Sie wirklich wollen „* . * "? Das schließt Dateien aus, die keinen Punkt im Namen haben. –

Antwort

3

Ein weiterer Option, mit Perl ist:

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

In nicht-Einzeiler-Format, das heißt:

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

Die while(<>){ Linie ist Perl Magie für Linien von Dateien auf dem Befehl oder aus STDIN lesen. Sie gewöhnen sich nach einer Weile daran. Die Zeile selbst geht in eine Variable namens $_, die der Standardparameter für viele Perl-Befehle ist. Zum Beispiel tr, die ziemlich ähnlich wie tr(1) funktioniert, standardmäßig auf $_. Ich setze meine Ergebnisse in eine globale Variable namens $c. (In einem vollständigen Programm ist es am besten, eine lexikalische Variable mit my $c = 0; außerhalb der Schleife zu deklarieren.) Der Operator += fügt das Ergebnis des Befehls tr (die Anzahl der Pipe-Zeichen in diesem Fall) zum aktuellen Wert $c hinzu.

Nur mit tr(1) ist eindeutig eine einfachere Option. ;-)

Die Verwendung von *.* ist ein DOSism, den Sie wahrscheinlich nicht auf einer UNIX-ähnlichen Plattform verwenden möchten.

Mit einfachen Anführungszeichen, um zu vermeiden, dass die Shell das Pipe-Zeichen interpretiert, wird ein bisschen besser gelesen. So testete ich meine Antwort mit:

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

.... wünschte, ich wüsste Perl. Python macht keine Einzeiler sehr gut. – Luis

-3

versuchen

grep -c "\|" *.* 

und einige Tutorials über bash lesen

+0

Gibt falsche Anzahl an, wenn mehrere Pipes in derselben Zeile sind. –

+0

Ja das ist mein Problem. – Luis

+0

Ich kann keine richtige Antwort auf eine Frage geben, wenn Sie es später ändern ... – siukurnin

10

Sie tr(1) können alle Nicht-Pipe-Zeichen zu löschen und dann wc(1) verwenden insgesamt zu erhalten:

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

Alte Schule und sehr nett. – dmckee

6

Es ist eingängig, aber in den meisten Unix-regex, das entweichende | macht es den oder-Operator. Ihre Zeile entspricht also "nichts oder nichts" (Sie können dies testen, indem Sie auf beiden Seiten einige Alternativen hinzufügen). Verwenden Sie einfach

grep -c "|" *.* 

Zweitens grep zählt Zeilen, nicht Zeichen Vorkommen. Sie könnten ein anderes Werkzeug verwenden; oder, wenn du auf grep bestehst, könntest du jedes "|" auf einer eigenen Linie. Zum Beispiel mit sed:

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

Hinweis: Wenn sed verwenden, rate ich eine Menge der Prüfung sicherstellen, dass es das tut, was Sie denken, es tut. Ich musste genau dann.

Schließlich verbinden die Zutaten:

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

Leider könnte dies nicht für Sie arbeiten, wie Sie wahrscheinlich nicht mit UNIX (wegen der *.*). Aber hoffentlich erklärt es das Problem, das ich immer seltsam beruhigend finde.

0

Wenn Sie eine Reihe von Rohren finden wollen, dann

fgrep -o "|" | wc -l 

Wenn Sie eine Anzahl von Leitungen mit mindestens einem Rohr finden wollen, dann

fgrep -c "|"