นับจำนวนอักขระที่เกิดขึ้นในสตริงโดยใช้ Bash


124

ฉันต้องการนับจำนวนครั้งที่เกิดขึ้นของอักขระในสตริงโดยใช้ Bash

ในตัวอย่างต่อไปเมื่อถ่านคือ (ตัวอย่าง) tมันechosหมายเลขที่ถูกต้องของการเกิดขึ้นของ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
@HattrickNZ แล้วใช้:$(grep -o "$needle" < filename | wc -l)
hek2mgl

13
@Amir คุณคาดหวังอะไร?
hek2mgl

3
คุณสามารถข้ามwc -lเพียงแค่ใช้grep -cมันทำงานได้ทั้ง bsd grep และ linux grep
andsens

8
@andsens grep -cจะแสดงผลตามจำนวนบรรทัดที่ตรงกันเท่านั้น ไม่นับการแข่งขันหลายรายการต่อบรรทัด
hek2mgl

1
ฉันต้องการนับ '$' ในสตริงฉันจะหนี '$' จากสตริงหลักได้อย่างไร
masT

118

ตัวอย่างเช่นคุณสามารถลบตัวอักษรอื่น ๆ ทั้งหมดและนับสิ่งที่ยังคงอยู่เช่น:

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

ทำไมถึงไม่ชอบwc? มันกอล์ฟ!
Ciro Santilli 郝海东冠状病六四事件法轮功

1
@CiroSantilli 六四事件法轮功包卓轩เพราะเช่นecho -n some line | wc -l
jm666

รหัสบล็อก 4 ดีที่สุดในความคิดของฉัน เราต้องทำให้ง่ายขึ้นเพื่อไปที่:tr -dc ',' <<<"$var" | wc -c
bgStack15

69

คุณสามารถทำได้โดยการรวมtrและwcคำสั่ง ตัวอย่างเช่นในการนับeในสตริง referee

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

เอาท์พุต

4

คำอธิบาย: คำสั่งtr -cd 'e'จะลบอักขระทั้งหมดที่ไม่ใช่ 'e' และ Command wc -cจะนับอักขระที่เหลือ

การป้อนข้อมูลหลายบรรทัดก็ดีสำหรับโซลูชันนี้เช่นคำสั่งcat mytext.txt | tr -cd 'e' | wc -cสามารถนับจำนวนeในไฟล์mytext.txtได้แม้คิดว่าไฟล์อาจมีหลายบรรทัด


3
วิธีแก้ปัญหาของคุณดูเหมือนจะสะอาดและจำง่ายที่สุดขอบคุณ!
jirislav

นี่มันเยี่ยมมาก ขอบคุณ!
Kodie Grantham

ฉันรักสิ่งนี้เพราะฉันเกลียดอ๊าก!
franzisk

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.