बैश का उपयोग करके एक स्ट्रिंग में चार की घटनाओं की गणना करें


123

मुझे बैश का उपयोग करके एक स्ट्रिंग में चार की घटनाओं की संख्या गिनने की आवश्यकता है ।

निम्न उदाहरण में, चार है जब (उदाहरण के लिए) t, यह echoहै की घटनाओं की सही संख्या tमें varहै, लेकिन जब चरित्र अल्पविराम या अर्धविराम है, यह शून्य बाहर प्रिंट:

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
@ हेट्रिकएनजेड का उपयोग करें:$(grep -o "$needle" < filename | wc -l)
hek2mgl

13
@Amir आप क्या उम्मीद करते हैं?
hek2mgl

3
आप इसे छोड़ सकते हैं wc -l, बस उपयोग कर सकते हैं grep -c, यह bsd grep और linux grep दोनों पर काम करता है।
andsens 11

8
@andsens grep -cकेवल मिलान लाइनों की संख्या को आउटपुट करेगा। यह प्रति पंक्ति कई मैचों की गणना नहीं करता है।
hek2mgl

1
मैं एक स्ट्रिंग में '$' की गिनती करना चाहता हूं, मैं मुख्य स्ट्रिंग से '$' कैसे बच सकता हूं?
मास्क '12

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"

1
यहाँ कुछ और ट्रिक जैसेy="${x//[^s|S]}"; echo "${#y}"
कुंभ राशि

4
पहले एक का उपयोग करें, इस तरह से काम करने के लिए हमेशा दूसरी प्रक्रिया का सहारा लेने से बचना चाहिए, यह बड़े चलना छोरों के साथ उपयोग करते समय प्रदर्शन को गंभीर रूप से प्रभावित कर सकता है। एक नियम के रूप में बाहरी प्रक्रिया का निष्पादन पुनरावृत्ति या दोहराए जाने वाले संचालन का उपयोग करते समय एक अंतिम उपाय होना चाहिए।
ओसिरिसगोत्रा

आपको पसंद क्यों नहीं है wc? यह गोल्फ!
सिरो सेंटिल्ली 郝海东 冠状 iro i 法轮功 ''

1
@CiroSantilli 六四 事件 包 卓 轩 example क्योंकि उदाहरण के लिएecho -n some line | wc -l
jm666

मेरी राय में कोड ब्लॉक 4 सबसे अच्छा है। हमें इसे पाने में आसान बनाने की आवश्यकता है:tr -dc ',' <<<"$var" | wc -c
bgStack15

68

आप इसे संयोजन trऔर wcकमांड के द्वारा कर सकते हैं । उदाहरण के लिए, eस्ट्रिंग में गणना करने के लिएreferee

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

उत्पादन

4

स्पष्टीकरण: कमांड tr -cd 'e''ई' के अलावा सभी वर्णों को हटा देता है, और कमांड wc -cशेष वर्णों को गिनता है।

इस समाधान के लिए इनपुट की कई लाइनें भी अच्छी हैं, जैसे कमांड फ़ाइल में cat mytext.txt | tr -cd 'e' | wc -cगणना कर सकता है , यहां तक ​​कि यह भी सोच सकता है कि फ़ाइल में कई लाइनें हो सकती हैं।emytext.txt


3
आपका समाधान सबसे साफ और याद रखने में आसान लगता है, धन्यवाद!
जिरिस्लाव

यह भी खूब रही। धन्यवाद!
कोडी ग्रन्थम

मुझे यह पसंद है, क्योंकि मुझे अजीब नफरत है!
फ्रैंकज़

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.