Zählen Sie das Auftreten eines Zeichens in einer Nur-Text-Datei

132

Gibt es unter Linux / Terminal eine Möglichkeit zu zählen, wie oft das Zeichen f in einer Nur-Text-Datei vorkommt?

Cupakob
quelle
9
Technisch könnte dies als sh / bash / etc. Programmierfrage, also denke ich, dass es an beiden Stellen Gültigkeit hat.
Rob Hruska
@Rob Hruska: Ja, ich denke auch Bash-Programmierung ... @abrashka: Die Antwort auf Ihre erste und zweite Frage lautet "NEIN"!
Cupakob

Antworten:

178

Wie wäre es damit:

fgrep -o f <file> | wc -l

Hinweis: Abgesehen davon, dass es viel einfacher ist, sich zu merken / zu duplizieren und anzupassen, ist dies ungefähr dreimal (sorry, bearbeiten! Den ersten Test verpfuscht) schneller als Verebs Antwort.

Cascabel
quelle
Dieser funktioniert nicht, wenn Sie zählen \roder \nZeichen benötigen ; Die tr -cd fAntwort funktioniert dafür.
Bjnord
3
Um mehrere Zeichen zu zählen, zum Beispiel a, bund cverwenden egrep: egrep -o 'a|b|c' <file> | wc -l.
Skippy le Grand Gourou
Achten Sie auch darauf, NICHT wc -cwie in der trAntwort zu verwenden: Da die grepAusgabe zeilenweise erfolgt, wcwürde das Zeilenende als Zeichen gezählt (wodurch sich die Anzahl der Zeichen verdoppelt).
Skippy le Grand Gourou
@bjnord Ok für \r, aber um zu zählen, \nwarum nicht einfach verwenden wc -l?
Skippy le Grand Gourou
67

noch schneller:

tr -cd f < file | wc -c

Zeit für diesen Befehl mit einer Datei mit 4,9 MB und 1100000 Vorkommen des gesuchten Zeichens:

real   0m0.089s
user   0m0.057s
sys    0m0.027s

Zeit für Vereb Antwort mit echo, cat, trund bcfür die gleiche Datei:

real   0m0.168s
user   0m0.059s
sys    0m0.115s

Zeit für Rob Hruska Antwort mit tr, sedund wcfür die gleiche Datei:

real   0m0.465s
user   0m0.411s
sys    0m0.080s

Zeit für Jefromi Antwort mit fgrepund wcfür die gleiche Datei:

real   0m0.522s
user   0m0.477s
sys    0m0.023s 
user1985553
quelle
3
Zu zählen mehrere Zeichen, zB a, bund c: tr -cd abc < file | wc -l.
Skippy le Grand Gourou
bist du sicher? sollte nicht tr -cd abc < file | wc -cstattdessen sein
Mithun B
10
echo $(cat <file>  | wc -c) - $(cat <file>  | tr -d 'A' | wc -c) | bc

wo das A das Zeichen ist

Zeit für diesen Befehl mit einer Datei mit 4,9 MB und 1100000 Vorkommen des gesuchten Zeichens:

real   0m0.168s
user   0m0.059s
sys    0m0.115s
Vereb
quelle
1
Dies wird ungefähr ein Drittel schneller, wenn Sie das unnötige cats entfernen und den Dateinamen als Argument für wcund angeben tr.
Cascabel
1
Wenn Sie dies wirklich optimieren möchten, wird die Datei nur einmal gelesen: echo $ (stat -c% s <Datei>) - $ (cat <Datei> | tr -d 'A' | wc -c) | bc
Vereb
@Vereb - tr liest nur stdin, aber das kann eher geleitet als cated:tr -d 'A' < <file> | wc ...
dsz
7

Wenn Sie nur die Anzahl der Zeilen zählen müssen, die Ihren Charakter enthalten, funktioniert dies:

grep -c 'f' myfile

Es werden jedoch mehrere Vorkommen von 'f' in derselben Zeile wie bei einer einzelnen Übereinstimmung gezählt.

Jongo der Gibbon
quelle
4

tr -d '\n' < file | sed 's/A/A\n/g' | wc -l

Ersetzen Sie die beiden Vorkommen von "A" durch Ihren Charakter und "Datei" durch Ihre Eingabedatei.

  • tr -d '\n' < file: Entfernt Zeilenumbrüche
  • sed 's/A/A\n/g: fügt nach jedem Auftreten von "A" eine neue Zeile hinzu
  • wc -l: zählt die Anzahl der Zeilen

Beispiel:

$ cat file
abcdefgabcdefgababababbbba


1234gabca

$ tr -d '\n' < file | sed 's/a/a\n/g' | wc -l
9
Rob Hruska
quelle