grep -c
Dies ist nützlich, um festzustellen, wie oft eine Zeichenfolge in einer Datei vorkommt, zählt jedoch jedes Vorkommen nur einmal pro Zeile. Wie zähle ich mehrere Vorkommen pro Zeile?
Ich suche etwas eleganteres als:
perl -e '$_ = <>; print scalar ( () = m/needle/g ), "\n"'
grep
es spezifiziert ist, aber für jedenack
, der es benutzt , ist die Antwort einfachack -ch <pattern>
.Antworten:
greps
-o
gibt nur die Übereinstimmungen aus und ignoriert die Zeilen.wc
kann sie zählen:Dies passt auch zu 'Nadeln' oder 'Mehrnadeln'.
Nur einzelne Wörter:
quelle
\b
und\B
macht man hier?uniq
entfernt nur benachbarte identische Zeilen, die Siesort
vor dem Füttern entfernen müssen,uniq
wenn Sie nicht bereits sicher sind, dass Duplikate immer unmittelbar benachbart sind.Wenn Sie GNU grep haben (immer unter Linux und Cygwin, gelegentlich an anderer Stelle), können Sie die Ausgangsleitungen von zählen
grep -o
:grep -o needle | wc -l
.Mit Perl gibt es einige Möglichkeiten, die ich eleganter finde als Ihre (auch nachdem sie behoben wurden ).
Wenn nur POSIX-Tools verwendet werden, besteht eine Möglichkeit darin, die Eingabe mit einer einzelnen Übereinstimmung in Zeilen aufzuteilen, bevor sie an grep übergeben wird. Wenn Sie beispielsweise nach ganzen Wörtern suchen, wandeln Sie zuerst jedes Nicht-Wort-Zeichen in eine neue Zeile um.
Andernfalls gibt es keinen Standardbefehl für diese spezielle Textverarbeitung. Sie müssen sich daher an sed (wenn Sie ein Masochist sind) oder awk wenden.
Hier ist eine einfachere Lösung mit
sed
undgrep
, die für Zeichenfolgen oder sogar reguläre Ausdrücke funktioniert, jedoch in einigen Eckfällen mit verankerten Mustern fehlschlägt (z. B. findet sie zwei Vorkommen von^needle
oder\bneedle
inneedleneedle
).Beachten Sie, dass ich in den obigen sed-Substitutionen
\n
einen Zeilenumbruch meinte. Dies ist Standard im Musterteil, aber im Ersetzungstext ersetzen Sie aus Gründen der Portabilität Backslash-Newline\n
.quelle
Wenn Sie, wie ich, tatsächlich
"beides, jedes genau einmal"wollten (dies ist tatsächlich "entweder; zweimal"), dann ist es ganz einfach:und überprüfen Sie die Ausgabe
2
.Der Vorteil dieses Ansatzes (wenn genau einmal ist , was Sie wollen) ist , dass es leicht skaliert werden kann .
quelle
Eine andere Lösung mit awk und
needle
als Feldtrenner:Wenn Sie eine Übereinstimmung
needle
gefolgt von Interpunktion wünschen , ändern Sie das Feldtrennzeichen entsprechendOder verwenden Sie die Klasse
[^[:alnum:]]
:, um alle Nicht-Alpha-Zeichen einzuschließen.quelle
In Ihrem Beispiel wird nur die Anzahl der Vorkommen pro Zeile und nicht die Gesamtsumme in der Datei gedruckt. Wenn es das ist, was Sie wollen, könnte so etwas funktionieren:
quelle
Dies ist meine reine Bash-Lösung
quelle