Zählen Sie das Vorkommen eines Zeichens in einer Zeichenfolge mit Bash


123

Ich muss die Anzahl der Vorkommen eines Zeichens in einer Zeichenfolge mit Bash zählen.

Im folgende Beispiel, wenn das Zeichen (zum Beispiel) ist t, es echos die richtige Anzahl von Vorkommen tin var, aber wenn das Zeichen Komma oder Semikolon ist, druckt es aus Null:

var = "text,text,text,text" 
num = `expr match $var [,]`
echo "$num"

Antworten:


117

Ich würde den folgenden awkBefehl verwenden:

string="text,text,text,text"
char=","
awk -F"${char}" '{print NF-1}' <<< "${string}"

Ich Aufspalten der Zeichenfolge durch $charund die Anzahl der resultierenden Felder minus 1 drucken.

Wenn Ihre Shell den <<<Operator nicht unterstützt , verwenden Sie echo:

echo "${string}" | awk -F"${char}" '{print NF-1}'

5
@ HattrickNZ Dann verwenden Sie:$(grep -o "$needle" < filename | wc -l)
hek2mgl

13
@Amir Was erwartest du?
hek2mgl

3
Sie können das überspringen wc -l, verwenden Sie grep -ces einfach , es funktioniert sowohl auf bsd grep als auch auf linux grep.
andsens

8
@andsens grep -cgibt nur die Anzahl der übereinstimmenden Zeilen aus. Es werden nicht mehrere Übereinstimmungen pro Zeile gezählt.
hek2mgl

1
Ich möchte '$' in einer Zeichenfolge zählen. Wie kann ich '$' aus der Hauptzeichenfolge entfernen?
MasT

117

Sie können zum Beispiel alle anderen Zeichen entfernen und die verbleibenden Zeichen zählen, z.

var="text,text,text,text"
res="${var//[^,]}"
echo "$res"
echo "${#res}"

wird gedruckt

,,,
3

oder

tr -dc ',' <<<"$var" | awk '{ print length; }'

oder

tr -dc ',' <<<"$var" | wc -c    #works, but i don't like wc.. ;)

oder

awk -F, '{print NF-1}' <<<"$var"

oder

grep -o ',' <<<"$var" | grep -c .

oder

perl -nle 'print s/,//g' <<<"$var"

1
einige weitere Tricks hier wiey="${x//[^s|S]}"; echo "${#y}"
Aquarius Power

4
Wenn Sie den ersten verwenden, sollten Sie immer vermeiden, einen anderen Prozess zu erzeugen, um diese Arbeit auszuführen. Dies kann die Leistung bei Verwendung mit großen Iterationsschleifen erheblich beeinträchtigen. In der Regel sollte die externe Prozessausführung ein letzter Ausweg sein, wenn iterierende oder sich wiederholende Operationen verwendet werden.
Osirisgothra

Warum magst du nicht wc? Es spielt Golf!
Ciro Santilli 法轮功 冠状 病 六四 事件 19

1
@CiroSantilli 轩 事件 法轮功 包 卓 卓 weil zum Beispielecho -n some line | wc -l
jm666

Codeblock 4 ist meiner Meinung nach der beste. Wir müssen es einfacher machen zu erreichen:tr -dc ',' <<<"$var" | wc -c
bgStack15

68

Sie können dies durch Kombinieren trund wcBefehlen tun . Zum Beispiel, um ein der Zeichenfolge zu zählenreferee

echo "referee" | tr -cd 'e' | wc -c

Ausgabe

4

Erläuterungen: Der Befehl tr -cd 'e'entfernt alle Zeichen außer 'e' und der Befehl wc -czählt die verbleibenden Zeichen.

Mehrzeiligen Eingabe sind auch gut für diese Lösung, wie Befehl cat mytext.txt | tr -cd 'e' | wc -ckann Zählungen ein der Datei mytext.txt, dachte auch die Datei viele Zeilen enthalten.


3
Ihre Lösung scheint die sauberste und am einfachsten zu merkende zu sein, danke!
Jirislav

Das ist toll. Danke dir!
Kodie Grantham

Ich liebe das, weil ich awk hasse!
Franzisk

3

Aufbauend auf den großartigen Antworten und Kommentaren aller ist dies die kürzeste und süßeste Version:

grep -o "$needle" <<< "$haystack" | wc -l


2

awk funktioniert gut, wenn Ihr Server es hat

var="text,text,text,text" 
num=$(echo "${var}" | awk -F, '{print NF-1}')
echo "${num}"

Nur als Hinweis: awk -F,sucht nach einem ,. Sie können Folgendes tun:awk -F"${your_char}"
Emixam23

1

Ich würde folgendes vorschlagen:

var="any given string"
N=${#var}
G=${var//g/}
G=${#G}
(( G = N - G ))
echo "$G"

Kein Aufruf eines anderen Programms


1

Schauen Sie sich das auch an, zum Beispiel wollen wir zählen t

echo "test" | awk -v RS='t' 'END{print NR-1}'

oder in python

python -c 'print "this is for test".count("t")'

oder noch besser, wir können unser Skript mit dynamisieren awk

echo 'test' | awk '{for (i=1 ; i<=NF ; i++) array[$i]++ } END{ for (char in array) print char,array[char]}' FS=""

In diesem Fall sieht die Ausgabe folgendermaßen aus:

e 1
s 1
t 2
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.