รับการนับจำนวนคำของไฟล์ข้อความของคำทั้งหมด & เรียงลำดับผลลัพธ์การพิมพ์


28

ฉันมีคำสั่งที่จะทำงานผ่านไฟล์ข้อความนับจำนวนคำทั้งหมดและพิมพ์ออกมาเช่นนี้

user@box $˜ magic-command-i-forgot | with grep | and awk | sort ./textfile.txt
66: the
54: and
32: I
16: unix
12: bash
5:  internet
3:  sh
1: GNU/Linux

ดังนั้นมันจึงไม่ค้นหาทีละบรรทัด แต่ใช้คำต่อคำและทำเพื่อทุกคำไม่ใช่แค่ 1 คำ ฉันพบมันที่ไหนสักแห่งใน internets นานมาแล้ว แต่ฉันไม่สามารถค้นหาหรือจำได้ ..

คำตอบ:


33

ฉันจะใช้trแทนawk :

echo "Lorem ipsum dolor sit sit amet et cetera." | tr '[:space:]' '[\n*]' | grep -v "^\s*$" | sort | uniq -c | sort -bnr
  • tr เพียงแทนที่ช่องว่างด้วยการขึ้นบรรทัดใหม่
  • grep -v "^\s*$" ตัดขอบเส้นที่ว่างเปล่า
  • sort เพื่อเตรียมเป็นอินพุตสำหรับ uniq
  • uniq -c เพื่อนับเหตุการณ์
  • sort -bnr เรียงลำดับย้อนกลับเป็นตัวเลขในขณะที่ละเว้นช่องว่าง

ว้าว. มันกลายเป็นคำสั่งที่ยอดเยี่ยมในการนับคำสาบานต่อบรรทัด

หา -name "* .py" -exec cat {} \; | tr '[: space:]' '[\ n *]' | grep -v "^ \ s * $" | จัดเรียง | uniq -c | sort -bnr | grep fuck


อาจต้องการใช้tr -sเพื่อจัดการช่องว่างหลายแห่งโดยเฉพาะเมื่อพบการเยื้อง
Arcege

@Arcege: จุดดี แม้ว่ามันจะไม่เปลี่ยนผลลัพธ์ แต่ก็อาจทำให้สคริปต์เร็วขึ้นเล็กน้อย
seler

-g( --general-numeric-sort) ตัวเลือกของsortอาจจะดีกว่าในบางกรณี เช่นsort -nจะให้10\n1 4ตามที่เป็นอยู่การรักษา1 4เป็น14ในขณะที่จะรักษามันอย่างถูกต้องตามsort -g 1 4\n10
Skippy le Grand Gourou

คำสั่งที่ดีจริงๆสมควรได้รับการโหวตขึ้น :)
นูร์

@seler ฉันคิดว่าคุณสามารถสร้าง grep และ tr part ได้ง่ายขึ้นเช่นด้านล่าง: echo "Lorem ipsum dolor sit sit amet et cetera." | tr ' ' '\n' | grep -v "^$" | sort | uniq -c | sort -bnrโปรดทราบว่าฉันเป็นผู้เริ่มต้นดังนั้นฉันอาจผิดโปรดอย่าลังเลที่จะให้คำแนะนำ
smc

8
  1. แยกอินพุตเป็นคำหนึ่งคำต่อบรรทัด
  2. เรียงรายการผลลัพธ์ของคำ (บรรทัด)
  3. สควอชหลายครั้ง
  4. เรียงตามจำนวนเหตุการณ์ที่เกิดขึ้น

หากต้องการแยกอินพุตเป็นคำให้แทนที่อักขระใด ๆ ที่คุณคิดว่าเป็นตัวคั่นคำด้วยบรรทัดใหม่

<input_file \
tr -sc '[:alpha:]' '[\n*]' | # Add digits, -, ', ... if you consider
                             # them word constituents
sort |
uniq -c |
sort -nr

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

5

ไม่ใช้ grep และ awk แต่ดูเหมือนว่าจะทำสิ่งที่คุณต้องการ:

for w in `cat maxwell.txt`; do echo $w; done|sort|uniq -c
  2 a
  1 A
  1 an
  1 command
  1 considered
  1 domain-specific
  1 for
  1 interpreter,
  2 is
  1 language.
  1 line
  1 of

1
สิ่งนี้จะไม่ทำงานหากอินพุตมีเชลล์ไวด์การ์ด (คุณต้องเพิ่มset -f) และใช้เครื่องหมายวรรคตอนเป็นส่วนหนึ่งของคำ (ซึ่งสามารถแก้ไขได้อย่างเชื่องช้าโดยการเพิ่มอักขระเครื่องหมายวรรคตอนให้IFS- โชคดีที่พยายามสนับสนุนชุดอักขระที่ไม่ใช่ ASCII) สิ่งนี้จะไม่ดีกับไฟล์อินพุตที่มีขนาดใหญ่มากเพราะมันจะเก็บไฟล์ทั้งหมดไว้ในหน่วยความจำ ( sortฉลาดกว่า)
Gilles 'หยุดความชั่วร้าย' ใน

2

ฉันเชื่อว่าคุณชอบอะไรแบบนี้?

$ perl -n -e 'foreach ${k} (split(/\s+/)){++$h{$k}};END{foreach $l (keys(%h)){print "$h{$l}: ${l}\n"}}' /path/to/your/file | sort -n -k 1

แน่นอนคุณสามารถทำเช่นเดียวกันกับawkเช่นกัน :)



0
file=/home/stefan/ooxml1.txt
for word in $(sed 's/[^A-Za-z]/ /g' $file | tr " " "\n" | sort -u)
do
  echo -n "$word "
  grep -c $word $file
done | sort -k2 -n 

เรียงลำดับจากน้อยไปมากหลังจากแยกไฟล์ออกเป็นคำต่างๆ

grep ง่ายจะพบfishในfisheyeเพื่อให้คุณมีเพื่อเพิ่มคำสั่ง grep เพื่อป้องกันไม่ให้การแข่งขันบางส่วน

ใช้เวลาประมาณ 3 วินาทีสำหรับไฟล์ข้อความ 25k บนเครื่องในยุคสมัย HDD แบบคลาสสิก (IDE)

สำหรับไฟล์ที่มีขนาดใหญ่กว่าหรือการดำเนินการที่มักจะใช้วิธีการแมปแฮชจะดีกว่า แต่สำหรับงานที่ไม่ค่อยจะรันหรือไฟล์ที่เล็กกว่าเท่านั้นมันอาจจะเพียงพอ

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