จะนับจำนวนคำทั้งหมดในไฟล์ได้อย่างไร?


18

ฉันกำลังมองหาคำสั่งเพื่อนับจำนวนคำทั้งหมดในไฟล์ เช่นถ้าไฟล์เป็นเช่นนี้

today is a 
good day

จากนั้นควรพิมพ์5เนื่องจากมี5คำอยู่


7
คุณเคยลองwc -w $FILEไหม
don_crissti

คำตอบ:


39

คำสั่งwcaka การนับจำนวนคำสามารถทำได้:

$ 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

1
โปรดทราบว่าคำสำหรับwc -wไม่ได้มีความหมายเช่นเดียวกับ grep -wGNU สำหรับwcคำคือลำดับของอักขระที่ไม่ใช่ช่องว่างหนึ่งอักขระขึ้นไป ( [:space:]คลาสอักขระในโลแคลปัจจุบัน) ตัวอย่างfoo,barและfoo bar(มีพื้นที่ที่ไม่หมด) แต่ละหนึ่งคำ
Stéphane Chazelas

7

ฉันมากับสิ่งนี้เพียงแค่ตัวเลข:

wc -w [file] | cut -d' ' -f1

5

ฉันชอบwc -w < [file]วิธีการเช่นกัน

สุดท้ายสำหรับการจัดเก็บเพียงจำนวนคำในตัวแปรคุณสามารถใช้ต่อไปนี้:

myVar=($(wc -w /path/to/file))

ซึ่งช่วยให้คุณข้ามชื่อไฟล์ได้อย่างสวยงาม


14
wc -w < "$file"สำหรับเพียงแค่จำนวน
Stéphane Chazelas

3

ทางออกที่ดีกว่าคือการใช้ 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เท่านั้น


13
ทำไมนี้ดีกว่า wc
Sparr

2
@Sparr สิ่งหนึ่งเพราะจะแปลกใจที่ดีมากของฉันมันดูเหมือนว่าจะมากได้เร็วขึ้น ฉันลองในไฟล์ข้อความที่มีคำ 1418,13504 คำและwcใช้เวลา ~ 14 วินาทีในขณะที่ Perl ใช้เวลา ~ 5sec!
terdon

3
ฉันคิดว่าปัญหา 'ที่ใหญ่กว่า' จริงๆคือคำตอบที่มีการพึ่งพา Perl และฉันไม่เคยเป็นแฟนตัวยงของการพึ่งพาดังกล่าว หากคำถามเกี่ยวกับการแสดงนั้นจะเป็นอีกเรื่องหนึ่ง
Michael Durrant

5
โปรดทราบว่าการsplitเปิด/\s+/เป็นเหมือนsplit(' ')ยกเว้นว่าช่องว่างนำใด ๆ ที่สร้างเขตข้อมูลแรกที่เป็นโมฆะ ความแตกต่างที่จะให้คุณหนึ่งคำพิเศษ (ฟิลด์แรก null ที่มี) ต่อสาย เชื่อมโยง ดังนั้นใช้(split(" ", $_))ไฟล์อื่นที่สร้างเช่นนี้: echo -e "unix\n linux" > testfileหนึ่งบรรทัดของคุณรายงาน 3 คำ
don_crissti

1
เวลาของคุณแสดงว่า wc เร็วขึ้น (เป็นเวลาของผู้ใช้และระบบที่สำคัญ) ด้วย LC_ALL = C, wcจะมีนัยสำคัญได้เร็วขึ้นเช่นเดียวกับPERLIO=:utf8, perlจะช้าลงอย่างมีนัยสำคัญ
Stéphane Chazelas

3

มาใช้ AWK กัน!

$ 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


มันนับคำดังนั้นมันดีพอสำหรับฉัน! :-)
aggsol

3

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

เปรียบเทียบจำนวน:

  • ใช้สคริปต์กับตัวเองให้ฉัน 76 คำ
  • ตัวอย่างใน Perl โดย @cuonglm ให้ 31
  • ใช้wcให้ 28

สำหรับการอ้างอิงPOSIX viพูดว่า:

ใน POSIX โลแคล vi จะรู้จักคำห้าชนิด:

  1. ลำดับตัวอักษรตัวเลขและขีดล่างสูงสุดคั่นด้วยปลายทั้งสองด้านโดย:

    • อักขระอื่นที่ไม่ใช่ตัวอักษรตัวเลขหรือขีดล่าง

    • จุดเริ่มต้นหรือจุดสิ้นสุดของบรรทัด

    • จุดเริ่มต้นหรือจุดสิ้นสุดของบัฟเฟอร์การแก้ไข

  2. ลำดับสูงสุดของอักขระนอกเหนือจากตัวอักษรตัวเลขเครื่องหมายขีดล่างหรืออักขระคั่นด้วยปลายทั้งสองด้านโดย:

    • ตัวอักษรตัวเลขขีดเส้นใต้
    • <blank> ตัวละคร
    • จุดเริ่มต้นหรือจุดสิ้นสุดของบรรทัด
    • จุดเริ่มต้นหรือจุดสิ้นสุดของบัฟเฟอร์การแก้ไข
  3. บรรทัดว่างต่อเนื่องหนึ่งบรรทัดหรือมากกว่า

  4. อักขระตัวแรกในบัฟเฟอร์การแก้ไข

  5. ไม่ใช่<newline>ในบัฟเฟอร์การแก้ไขล่าสุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.