Bashを使用して文字列内の文字の出現をカウントする


123

Bashを使用して文字列内のcharの出現回数を数える必要があります。

次の例では、チャー(例えば)である場合、tそれは、echosはの出現の正確な数tvarはなく、文字はコンマまたはセミコロンである場合、それはゼロを出力します:

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

回答:


118

次のawkコマンドを使用します。

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

文字列を分割して$char、結果のフィールドから1を引いた数を出力します。

シェルが<<<演算子をサポートしていない場合は、次を使用しますecho

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

5
@HattrickNZは次に使用:$(grep -o "$needle" < filename | wc -l)
hek2mgl

13
@アミール何を期待していますか?
hek2mgl 2014

3
あなたはスキップすることができwc -l、ただ使うだけでgrep -c、それはbsd grepとlinux grepの両方で動作します。
andsens

8
@andsens grep -cは一致する行の数のみを出力します。1行あたりの複数の一致はカウントされません。
hek2mgl

1
文字列内の「$」を数えたいのですが、「$」をメイン文字列からエスケープするにはどうすればよいですか?
2018

117

たとえば、次のように他のすべての文字を削除して、残っているものを数えることができます。

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

印刷します

,,,
3

または

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

または

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

または

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

または

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

または

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


4
最初のものを使用します。このような作業を行うために別のプロセスを生成することを常に避ける必要があります。大きな反復ループで使用すると、パフォーマンスに深刻な影響を与える可能性があります。原則として、反復または繰り返し操作を使用する場合、外部プロセスの実行は最後の手段でなければなりません。
osirisgothra 14年

どうして好きwcじゃないの?ゴルフ!
Ciro Santilli郝海东冠状病六四事件法轮功

1
@CiroSantilli六四事件法轮功包卓轩たとえばecho -n some line | wc -l
jm666 '20

コードブロック4は私の意見では最高です。私たちは、それが簡単に取得するために行う必要がありますtr -dc ',' <<<"$var" | wc -c
bgStack15

68

trwcコマンドを組み合わせて実行できます。たとえばe、文字列を数えるには referee

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

出力

4

説明:コマンドtr -cd 'e'は「e」以外のすべての文字を削除し、コマンドwc -cは残りの文字をカウントします。

複数行の入力もこのソリューションに適しています。たとえば、ファイルに多数の行が含まれている場合でも、command cat mytext.txt | tr -cd 'e' | wc -ceファイル内mytext.txtでカウントできるようになります。


3
あなたの解決策は最もクリーンで覚えやすいようです、ありがとう!
ジリスラフ2018

これは素晴らしい。ありがとうございました!
コディグランサム

私はこれが好きです、なぜなら私はawkが嫌いだからです!
フランジスク

3

みんなの素晴らしい答えとコメントを基にして、これは最も短くて甘いバージョンです:

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


2

あなたのサーバーにawkがあればうまくいきます

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

ちょうどメモとして:をawk -F,探し,ます。あなたは、次の操作を行うことができますawk -F"${your_char}"
Emixam23

1

私は以下を提案します:

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

他のプログラムへの呼び出しはありません


1

これもチェックしてください。たとえば、 t

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

または python

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

またはさらに良いことに、スクリプトを動的にすることができます awk

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

この場合、出力は次のようになります。

e 1
s 1
t 2
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.