2013-05-21 15 views
62

Należy liczyć liczbę wystąpień znaku w ciągu przy użyciu Bash.Liczba wystąpień znaku w ciągu znaków przy użyciu Bash

W następującym przykładzie, gdy znak jest (na przykład) t to echo s prawidłowa liczba wystąpień t w var, ale gdy postać przecinek lub średnik, drukuje się Zero

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

http: //unix.stackexchange.com/questions/18736/how-to-count-of-a-specific-character-in-each-line –

Odpowiedz

66

chciałbym użyć następującego polecenia: awk

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

jestem dzielenie ciąg przez $char i wydrukować liczbę wynikających pól minus 1.

Jeśli powłoka nie obsługuje operatora <<< użyć echo:

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

co jeśli plik var jest plikiem z tekstem. jak można to zmienić? – HattrickNZ

+0

@HattrickNZ Następnie użyj: '$ (grep -o" $ needle " hek2mgl

+0

@ hek2mgi. ale ten wyprowadza 3?! kiedy jestem echo "number_of_occurences" – Amir

68

można na przykład usunąć wszystkie inne znaki i liczyć Co pozostaje, jak :

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

wypisze

,,, 
3 

lub

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

lub

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

lub

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

lub

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

lub

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

[trochę więcej tricków tutaj] (http://www.cyberciti.biz/faq/unix-linux-appleosx-bsd-bash-count-characters-variables/) takich jak 'y =" $ {x // [^ s | S]} "; echo "$ {# y}" ' –

+4

użyj pierwszego, powinieneś zawsze unikać uciekania się do kolejnego procesu do wykonania takiej pracy, może to poważnie wpłynąć na wydajność podczas używania z dużymi pętlami iteracyjnymi. Z reguły wykonanie procesu zewnętrznego powinno być ostatecznością w przypadku korzystania z powtarzania lub powtarzania operacji. – osirisgothra

+0

Dlaczego nie lubisz "wc"? To gra w golfa! –

1

awk działa dobrze, jeśli serwer ma to

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

Można to zrobić poprzez połączenie tr i wc poleceń. Na przykład, aby liczyć e w ciągu referee

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

wyjściowego

4 

Objaśnienia: Polecenie tr -cd 'e' usuwa wszystkie znaki inne niż 'e', ​​a Komenda wc -c liczy pozostałe znaki.

Wiele linii wejścia są również dobre dla tego rozwiązania, podobnie jak komendy cat mytext.txt | tr -cd 'e' | wc -c puszka liczy e w pliku mytext.txt, mimo że plik może zawierać wiele linii.

+0

Twoje rozwiązanie wydaje się najczystsze i najłatwiejsze do zapamiętania, dzięki! – jirislav

Powiązane problemy