Policz wystąpienia znaku w zwykłym pliku tekstowym

132

Czy w linux / terminalu jest sposób, aby policzyć, ile razy znak f występuje w zwykłym pliku tekstowym?

cupakob
źródło
9
Technicznie można to uznać za sh / bash / etc. pytanie programistyczne, więc myślę, że ma to znaczenie w każdym miejscu.
Rob Hruska
@Rob Hruska: tak, ja też myślę, że to programowanie w bashu ... @abrashka: odpowiedź na twoje pierwsze i drugie pytanie brzmi „NIE”!
cupakob

Odpowiedzi:

180

Co powiesz na to:

fgrep -o f <file> | wc -l

Uwaga: Poza tym, że jest to dużo łatwiejsze do zapamiętania / powielenia i dostosowania, jest to około trzy razy (przepraszam, edycja! Spartaczył pierwszy test) szybciej niż odpowiedź Vereba.

Cascabel
źródło
Ten nie działa, jeśli potrzebujesz liczyć \rlub \nznaków; tr -cd fodpowiedź działa za to.
bjnord
3
Aby policzyć kilka znaków, np a, bi cużyć egrep: egrep -o 'a|b|c' <file> | wc -l.
Skippy le Grand Gourou
Uważaj również, aby NIE używać tego, wc -cco w trodpowiedzi: ponieważ grepwyjścia wiersz po wierszu wczliczałyby końce wierszy jako znaki (stąd podwojenie liczby znaków).
Skippy le Grand Gourou
@bjnord Ok \r, ale żeby policzyć, \ndlaczego nie po prostu użyć wc -l?
Skippy le Grand Gourou
69

nawet szybciej:

tr -cd f < file | wc -c

Czas na to polecenie z plikiem o wielkości 4,9 MB i 1100000 wystąpień szukanego znaku:

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

Czas na Vereb odpowiedzi z echo, cat, tri bcdla tego samego pliku:

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

Czas na Rob HRUŠKA odpowiedzieć tr, sedi wcdla tego samego pliku:

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

Czas na odpowiedź Jefromiego z fgrepi wcdla tego samego pliku:

real   0m0.522s
user   0m0.477s
sys    0m0.023s 
user1985553
źródło
3
Aby policzyć kilka znaków, na przykład a, bi c: tr -cd abc < file | wc -l.
Skippy le Grand Gourou
Jesteś pewny? nie miał być tr -cd abc < file | wc -czamiast tego
Mithun B
10
echo $(cat <file>  | wc -c) - $(cat <file>  | tr -d 'A' | wc -c) | bc

gdzie A to znak

Czas na to polecenie z plikiem o wielkości 4,9 MB i 1100000 wystąpień szukanego znaku:

real   0m0.168s
user   0m0.059s
sys    0m0.115s
Vereb
źródło
1
Robi się to około jedną trzecią szybciej, jeśli usuniesz niepotrzebne catpliki, podając nazwę pliku jako argument do wci tr.
Cascabel
1
Jeśli naprawdę chcesz zoptymalizować, czyta plik tylko raz: echo $ (stat -c% s <plik>) - $ (cat <plik> | tr -d 'A' | wc -c) | bc
Vereb
@Vereb - tr tylko czyta stdin, ale to może być raczej przesyłane niż cated:tr -d 'A' < <file> | wc ...
dsz
7

Jeśli wszystko, co musisz zrobić, to policzyć liczbę linii zawierających twoją postać, zadziała:

grep -c 'f' myfile

Jednak zlicza wielokrotne wystąpienia „f” w tym samym wierszu jako pojedyncze dopasowanie.

Jongo the Gibbon
źródło
4

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

Zastąpienie dwóch wystąpień „A” swoim znakiem i „plikiem” plikiem wejściowym.

  • tr -d '\n' < file: usuwa nowe linie
  • sed 's/A/A\n/g: dodaje nowy wiersz po każdym wystąpieniu „A”
  • wc -l: liczy liczbę linii

Przykład:

$ cat file
abcdefgabcdefgababababbbba


1234gabca

$ tr -d '\n' < file | sed 's/a/a\n/g' | wc -l
9
Rob Hruska
źródło