ฉันกำลังมองหาคำสั่งเพื่อนับจำนวนคำทั้งหมดในไฟล์ เช่นถ้าไฟล์เป็นเช่นนี้
today is a
good day
จากนั้นควรพิมพ์5
เนื่องจากมี5
คำอยู่
ฉันกำลังมองหาคำสั่งเพื่อนับจำนวนคำทั้งหมดในไฟล์ เช่นถ้าไฟล์เป็นเช่นนี้
today is a
good day
จากนั้นควรพิมพ์5
เนื่องจากมี5
คำอยู่
คำตอบ:
คำสั่งwc
aka การนับจำนวนคำสามารถทำได้:
$ wc -w <file>
$ cat sample.txt
today is a
good day
$ wc -w sample.txt
5 sample.txt
# just the number (thanks to Stephane Chazelas' comment)
$ wc -w < sample.txt
5
wc -w
ไม่ได้มีความหมายเช่นเดียวกับ grep -w
GNU สำหรับwc
คำคือลำดับของอักขระที่ไม่ใช่ช่องว่างหนึ่งอักขระขึ้นไป ( [:space:]
คลาสอักขระในโลแคลปัจจุบัน) ตัวอย่างfoo,bar
และfoo bar
(มีพื้นที่ที่ไม่หมด) แต่ละหนึ่งคำ
ฉันมากับสิ่งนี้เพียงแค่ตัวเลข:
wc -w [file] | cut -d' ' -f1
5
ฉันชอบwc -w < [file]
วิธีการเช่นกัน
สุดท้ายสำหรับการจัดเก็บเพียงจำนวนคำในตัวแปรคุณสามารถใช้ต่อไปนี้:
myVar=($(wc -w /path/to/file))
ซึ่งช่วยให้คุณข้ามชื่อไฟล์ได้อย่างสวยงาม
wc -w < "$file"
สำหรับเพียงแค่จำนวน
ทางออกที่ดีกว่าคือการใช้ Perl:
perl -nle '$word += scalar(split(/\s+/, $_)); END{print $word}' filename
@Bernhard
คุณสามารถตรวจสอบซอร์สโค้ดของwc
คำสั่งจาก coreutils ฉันทดสอบในเครื่องของฉันด้วยไฟล์subst.c
ในแหล่งทุบตี 4.2
time wc -w subst.c
real 0m0.025s
user 0m0.016s
sys 0m0.000s
และ
time perl -nle '$word += scalar(split(" ", $_)); END{print $word}' subst.c
real 0m0.021s
user 0m0.016s
sys 0m0.004s
ยิ่งไฟล์มีขนาดใหญ่เท่าใด Perl ก็จะมีประสิทธิภาพมากขึ้นwc
เท่านั้น
wc
ใช้เวลา ~ 14 วินาทีในขณะที่ Perl ใช้เวลา ~ 5sec!
split
เปิด/\s+/
เป็นเหมือนsplit(' ')
ยกเว้นว่าช่องว่างนำใด ๆ ที่สร้างเขตข้อมูลแรกที่เป็นโมฆะ ความแตกต่างที่จะให้คุณหนึ่งคำพิเศษ (ฟิลด์แรก null ที่มี) ต่อสาย เชื่อมโยง ดังนั้นใช้(split(" ", $_))
ไฟล์อื่นที่สร้างเช่นนี้: echo -e "unix\n linux" > testfile
หนึ่งบรรทัดของคุณรายงาน 3 คำ
wc
จะมีนัยสำคัญได้เร็วขึ้นเช่นเดียวกับPERLIO=:utf8
, perl
จะช้าลงอย่างมีนัยสำคัญ
$ function wordfrequency() { awk 'BEGIN { FS="[^a-zA-Z]+" } { for (i=1; i<=NF; i++) { word = tolower($i) words[word]++ } } END { for (w in words) printf("%3d %s\n", words[w], w) } ' | sort -rn }
$ cat your_file.txt | wordfrequency
รายการนี้แสดงความถี่ของแต่ละคำที่เกิดขึ้นในไฟล์ที่ให้ไว้ ฉันรู้ว่าไม่ใช่สิ่งที่คุณขอ แต่ก็ดีกว่า! หากคุณต้องการที่จะเห็นการเกิดขึ้นของคำของคุณคุณสามารถทำได้:
$ cat your_file.txt | wordfrequency | grep yourword
ฉันยังเพิ่มฟังก์ชั่นนี้ในไฟล์. docของฉันด้วย
ที่มา: AWK-Ward Ruby
wc
นับโปรแกรม "คำว่า" แต่ผู้ที่ไม่ได้สำหรับอินสแตนซ์ "คำว่า" ที่หลาย ๆ คนจะได้เห็นเมื่อพวกเขาตรวจสอบไฟล์ vi
โปรแกรมเช่นใช้มาตรการที่แตกต่างกันของ "คำพูด" delimiting พวกเขาอยู่บนพื้นฐานของการเรียนตัวของพวกเขาในขณะที่wc
เพียงแค่นับสิ่งที่แยกจากกันโดยช่องว่าง มาตรการทั้งสองอาจแตกต่างกันอย่างสิ้นเชิง ลองพิจารณาตัวอย่างนี้:
first,second
vi
เห็นคำสามคำ (ตัวแรกและตัวที่สองเช่นเดียวกับเครื่องหมายจุลภาคคั่นพวกเขา) ในขณะที่wc
เห็นหนึ่งคำ (ไม่มีช่องว่างในบรรทัดนั้น) มีหลายวิธีในการนับคำบางคำมีประโยชน์น้อยกว่าคำอื่น ๆ
ในขณะที่ Perl จะเหมาะดีกว่าที่จะเขียนเคาน์เตอร์สำหรับคำ vi สไตล์ที่นี่เป็นตัวอย่างรวดเร็วโดยใช้sed
, tr
และwc
(แบบพกพาในระดับปานกลางโดยใช้ผลตอบแทนการขนส่งตัวอักษร^M
):
#!/bin/sh
in_words="[[:alnum:]_]"
in_punct="[][{}\\|:\"';<>,./?\`~!@#$%^&*()+=-]"
sed -e "s/\($in_words\)\($in_punct\)/\1^M\2/g" \
-e "s/\($in_punct\)\($in_words\)/\1^M\2/g" \
-e "s/[[:space:]]/^M/g" \
"$@" |
tr '\r' '\n' |
sed -e '/^$/d' |
wc -l
เปรียบเทียบจำนวน:
wc
ให้ 28สำหรับการอ้างอิงPOSIX viพูดว่า:
ใน POSIX โลแคล vi จะรู้จักคำห้าชนิด:
ลำดับตัวอักษรตัวเลขและขีดล่างสูงสุดคั่นด้วยปลายทั้งสองด้านโดย:
อักขระอื่นที่ไม่ใช่ตัวอักษรตัวเลขหรือขีดล่าง
จุดเริ่มต้นหรือจุดสิ้นสุดของบรรทัด
จุดเริ่มต้นหรือจุดสิ้นสุดของบัฟเฟอร์การแก้ไข
ลำดับสูงสุดของอักขระนอกเหนือจากตัวอักษรตัวเลขเครื่องหมายขีดล่างหรืออักขระคั่นด้วยปลายทั้งสองด้านโดย:
- ตัวอักษรตัวเลขขีดเส้นใต้
<blank>
ตัวละคร- จุดเริ่มต้นหรือจุดสิ้นสุดของบรรทัด
- จุดเริ่มต้นหรือจุดสิ้นสุดของบัฟเฟอร์การแก้ไข
บรรทัดว่างต่อเนื่องหนึ่งบรรทัดหรือมากกว่า
อักขระตัวแรกในบัฟเฟอร์การแก้ไข
ไม่ใช่
<newline>
ในบัฟเฟอร์การแก้ไขล่าสุด
wc -w $FILE
ไหม