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

ฉันกำลังพยายามนับคำใดคำหนึ่งที่เกิดขึ้นในไดเร็กทอรีทั้งหมด เป็นไปได้ไหม?

ตัวอย่างเช่น มีไดเร็กทอรีที่มีไฟล์ 100 ไฟล์ ซึ่งไฟล์ทั้งหมดอาจมีคำว่า "aaa" อยู่ในนั้น ฉันจะนับจำนวน “aaa” ในไฟล์ทั้งหมดภายใต้ไดเรกทอรีนั้นได้อย่างไร

ฉันลองสิ่งที่ชอบ:

 zegrep "xception" `find . -name '*auth*application*' | wc -l 

แต่มันไม่ทำงาน


person Ashish Sharma    schedule 26.05.2011    source แหล่งที่มา


คำตอบ (7)


grep -roh aaa . | wc -w

Grep จะเรียกไฟล์และไดเร็กทอรีทั้งหมดซ้ำใน dir ปัจจุบันที่ค้นหา aaa และส่งออกเฉพาะรายการที่ตรงกัน ไม่ใช่ทั้งบรรทัด จากนั้นเพียงใช้ wc เพื่อนับว่ามีกี่คำ

person Carlos Campderrós    schedule 26.05.2011
comment
นอกจากนี้ หากคุณไม่ต้องการการจับคู่จริง เพียงนับเท่านั้น คุณสามารถใช้ grep -rcP '^aaa$' . ซึ่งจะช่วยประหยัดการไปป์และป้องกันการฝัง 'aaa' - person cgledezma; 30.07.2013
comment
@cgledezma จุดดีเกี่ยวกับ -c แต่จะล้มเหลวหากมี searchString เกิดขึ้นสองครั้งขึ้นไปในหนึ่งบรรทัด - person Carlos Campderrós; 30.07.2013
comment
MM... อันที่จริง ฉันไม่ได้สังเกตเห็นว่ามันนับเฉพาะจำนวนบรรทัดที่ตรงกันเท่านั้น ไม่ใช่จำนวนการแข่งขันจริง แต่ฉันก็ยังคิดว่าการวางขอบเขตของคำนั้นอาจมีประโยชน์เพื่อหลีกเลี่ยงการจับคู่ที่ซ้อนกัน ขออภัย ฉันวางไว้ไม่ถูกต้องในความคิดเห็นก่อนหน้า: grep -rohP '\baaa\b . | wc -w - person cgledezma; 30.07.2013
comment
@cgledezma แน่นอนว่าขอบเขตของคำอาจมีประโยชน์ในบางสถานการณ์ - person Carlos Campderrós; 30.07.2013
comment
ในโซลูชันของ osx @cgledezma แปลเป็น grep -rohe '\baaa\b . | wc -w เนื่องจาก -P ไม่พร้อมใช้งาน - person IanBussieres; 07.05.2015
comment
สิ่งหนึ่งที่ควรทราบก็คือ หากคุณค้นหารูปแบบที่มีช่องว่างระหว่างคำหรือตัวอักษรหลายคำ เช่น grep -roh 'global \$' . หรือ grep -roh 'one two' . จากนั้นเมื่อไปไพพ์ที่ wc -w มันจะนับคำทั้งหมด ดังนั้นคุณอาจต้องการนับเฉพาะจำนวนคำที่ตรงกันทั้งหมด ไม่ใช่จำนวนคำทั้งหมดในผลลัพธ์ ฉันทำได้โดยการไพพ์ไปที่ grep อีกครั้ง แต่ค้นหาคำแรกเท่านั้น เช่น grep -roh 'global \$' . | grep -o 'global' | wc -w แต่อาจจะเป็นวิธีที่สง่างามกว่า? - person mrjamesmyers; 06.03.2018

โซลูชันอื่นที่ใช้ find และ grep

find . -type f -exec grep -o aaa {} \; | wc -l

ควรจัดการชื่อไฟล์ที่มีการเว้นวรรคอย่างถูกต้อง

person Fredrik Pihl    schedule 28.05.2011
comment
สมบูรณ์แบบ! ฉันใช้การค้นหาตามขนาด ซึ่งทำงานได้อย่างสมบูรณ์แบบ - person SeanDowney; 29.09.2011
comment
@Fredrik: สิ่งนี้ทำงานได้อย่างสมบูรณ์แบบ แต่มีวิธีนับคำโดยหลีกเลี่ยงการนับคำนั้นหลายครั้งในไฟล์เดียวกันหรือไม่ เช่น ถ้าคำว่า aaa ปรากฏใน file1.txt 10 ครั้ง แต่จำนวนควรเพิ่มขึ้นเพียง 1 แต่ไม่ใช่ 10 และในทำนองเดียวกันในไฟล์อื่นๆ ภายในไดเร็กทอรีด้วย - person annunarcist; 09.11.2013
comment
@annunarcist -- ใช่ มันสามารถทำได้ โพสต์คำถามใหม่แล้วฉันจะดู :-) - person Fredrik Pihl; 09.11.2013
comment
@Fredrik : โพสต์แล้ว! นี่คือ ลิงก์ - person annunarcist; 09.11.2013

ใช้ grep ด้วยวิธีที่ง่ายที่สุด ลอง grep --help เพื่อดูข้อมูลเพิ่มเติม


  1. หากต้องการนับจำนวนคำในไฟล์เฉพาะ:

    grep -c <word> <file_name>
    

    ตัวอย่าง:

    grep -c 'aaa' abc_report.csv
    

    เอาท์พุท:

    445
    

  1. หากต้องการนับจำนวนคำใน ทั้งไดเร็กทอรี:

    grep -c -R <word>
    

    ตัวอย่าง:

    grep -c -R 'aaa'
    

    เอาท์พุท:

    abc_report.csv:445
    lmn_report.csv:129
    pqr_report.csv:445
    my_folder/xyz_report.csv:408
    
person Parag Tyagi    schedule 13.03.2016

มาใช้ 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

หากต้องการค้นหาคำของคุณในไฟล์ทั้งหมดในไดเร็กทอรี (แบบไม่เรียกซ้ำ) คุณสามารถทำได้:

$ cat * | wordfrequency | grep yourword

หากต้องการค้นหาคำของคุณในไฟล์ทั้งหมดในไดเร็กทอรี (และไดเร็กทอรีย่อย) คุณสามารถทำได้:

$ find . -type f | xargs cat | wordfrequency | grep yourword

ที่มา: AWK-ward Ruby

person Sheharyar    schedule 15.12.2014

รวมไฟล์เข้าด้วยกันและ grep เอาต์พุต: cat $(find /usr/share/doc/ -name '*.txt') | zegrep -ic '\<exception\>'

หากคุณต้องการให้ 'พิเศษ' ตรงกัน อย่าใช้ '\‹' และ '\>' ครอบคำ

person jcomeau_ictx    schedule 26.05.2011

เริ่มต้นด้วย:

cat * | sed 's/ /\n/g' | grep '^aaa$' | wc -l

ดังข้อความต่อไปนี้:

pax$ cat file1
this is a file number 1

pax$ cat file2
And this file is file number 2,
a slightly larger file

pax$ cat file[12] | sed 's/ /\n/g' | grep 'file$' | wc -l
4

sed แปลงช่องว่างเป็นบรรทัดใหม่ (คุณอาจต้องการรวมอักขระเว้นวรรค อื่นๆ เช่นเดียวกับแท็บ ด้วย sed 's/[ \t]/\n/g') grep เพิ่งได้รับบรรทัดที่มีคำที่ต้องการ จากนั้น wc จะนับบรรทัดเหล่านั้นสำหรับคุณ

ขณะนี้อาจมีกรณีขอบที่สคริปต์นี้ใช้งานไม่ได้ แต่ควรจะโอเคสำหรับสถานการณ์ส่วนใหญ่

หากคุณต้องการ tree ทั้งหมด (ไม่ใช่แค่ระดับไดเร็กทอรีเดียว) คุณสามารถใช้สิ่งต่อไปนี้:

( find . -name '*.txt' -exec cat {} ';' ) | sed 's/ /\n/g' | grep '^aaa$' | wc -l
person paxdiablo    schedule 26.05.2011

นอกจากนี้ยังมีไวยากรณ์ grep regex สำหรับคำที่ตรงกันเท่านั้น:

# based on Carlos Campderrós solution posted in this thread
man grep | less -p '\<'
grep -roh '\<aaa\>' . | wc -l

สำหรับไวยากรณ์การจับคู่คำอื่น regex โปรดดู:

man re_format | less -p '\[\[:<:\]\]'
person tim    schedule 28.05.2011