ฉันมีไฟล์ JSON ขนาดใหญ่ที่อยู่บนบรรทัดเดียวและฉันต้องการใช้บรรทัดคำสั่งเพื่อให้สามารถนับจำนวนคำที่เกิดขึ้นในไฟล์ได้ ฉันจะทำสิ่งนั้นได้อย่างไร
ฉันมีไฟล์ JSON ขนาดใหญ่ที่อยู่บนบรรทัดเดียวและฉันต้องการใช้บรรทัดคำสั่งเพื่อให้สามารถนับจำนวนคำที่เกิดขึ้นในไฟล์ได้ ฉันจะทำสิ่งนั้นได้อย่างไร
คำตอบ:
$ tr ' ' '\n' < FILE | grep WORD | wc -l
โดยtr
แทนที่ช่องว่างด้วยการขึ้นบรรทัดใหม่ให้grep
กรองบรรทัดผลลัพธ์ทั้งหมดที่ตรงกับ WORD และwc
นับจำนวนที่เหลือ
หนึ่งสามารถบันทึกwc
ส่วนโดยใช้-c
ตัวเลือกของ grep:
$ tr ' ' '\n' < FILE | grep -c WORD
-c
ตัวเลือกที่ถูกกำหนดโดย POSIX
หากไม่รับประกันว่ามีช่องว่างระหว่างคำคุณต้องใช้อักขระอื่น (เป็นตัวคั่น) เพื่อแทนที่ ตัวอย่างเช่นtr
ชิ้นส่วนทางเลือกคือ
tr '"' '\n'
หรือ
tr "'" '\n'
หากคุณต้องการแทนที่เครื่องหมายคำพูดคู่หรือคำเดี่ยว แน่นอนคุณยังสามารถใช้tr
เพื่อแทนที่อักขระหลายตัวพร้อมกัน (คิดว่าช่องว่างและเครื่องหมายวรรคตอนต่าง ๆ )
ในกรณีที่คุณต้องการนับ WORD แต่ไม่ใช่ prefixWORD, WORDsuffix หรือ prefixWORDsuffix คุณสามารถใส่รูปแบบ WORD ในเครื่องหมายเริ่มต้น / สิ้นสุดของบรรทัด:
grep -c '^WORD$'
ซึ่งเทียบเท่ากับเครื่องหมายคำเริ่มต้น / สิ้นสุดในบริบทของเรา:
grep -c '\<WORD\>'
tr
คำสั่งที่ทำงานแทนการแนะนำตัวอย่างที่จะไม่ทำงานในทุกสถานการณ์ นอกจากนี้ยังจะจับคู่คำที่มีคำที่คุณต้องการ การgrep -o '\<WORD\>' | wc -l
แก้ปัญหานั้นเหนือกว่ามาก
ด้วย GNU grep สิ่งนี้ใช้ได้ผล: grep -o '\<WORD\>' | wc -l
-o
พิมพ์แต่ละส่วนที่ตรงกันของแต่ละบรรทัดในบรรทัดแยก
\<
ยืนยันจุดเริ่มต้นของคำและ\>
ยืนยันจุดสิ้นสุดของคำ (คล้ายกับ Perl ของ\b
) เพื่อให้แน่ใจว่าคุณไม่ได้จับคู่สตริงตรงกลางคำ
ตัวอย่างเช่น,
$ python -c 'นำเข้าสิ่งนี้' | grep '\ <one \>' ควรจะมีหนึ่ง - และโดยเฉพาะเพียงหนึ่งวิธี --obvious ที่จะทำมัน Namespaces เป็นหนึ่งในแนวคิดที่ยอดเยี่ยม - ลองทำสิ่งเหล่านี้ให้มากขึ้น! $ python -c 'นำเข้าสิ่งนี้' | grep -o '\ <one \>' one one one $ python -c 'นำเข้าสิ่งนี้' | grep -o '\ <one \>' | ห้องสุขา -l 3
grep -wo WORD | wc -l
นี้น่าเสียดายที่ไม่ได้ทำงานกับ coreutils
GNU
grep -o -c WORD file
หากใช้งานได้บนแพลตฟอร์มของคุณมันเป็นโซลูชันที่สวยงามและใช้งานง่าย แต่คน GNU ยังคงคิด
grep
มีข้อผิดพลาดที่นี่ ยังไม่ชัดเจนจาก POSIX ความหมายของการรวมกัน-c
และ-o
ควรเป็นเช่นนี้ในปัจจุบันไม่สามารถพกพาได้ ขอบคุณสำหรับความคิดเห็น; ฉันได้อัปเดตคำตอบนี้แล้ว
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl
คำสั่งนี้ทำสิ่งต่อไปนี้:
ตัวอย่างเช่นถ้าฉันต้องการวิเคราะห์ข้อความ Linus Torvald แรก:
จาก: torvalds@klaava.Helsinki.FI (กลุ่มข่าว Linus Benedict Torvalds): comp.os.minix หัวเรื่อง: คุณอยากเห็นอะไรใน minix มากที่สุด? สรุป: แบบสำรวจขนาดเล็กสำหรับระบบปฏิบัติการใหม่ของฉันข้อความ -ID: <1991Aug25.205708.9541@klaava.Helsinki.FI> วันที่: 25 ส.ค. 91 20:57:08 GMT องค์กร: มหาวิทยาลัยเฮลซิงกิ
สวัสดีทุกคนที่อยู่ที่นั่นโดยใช้ minix -
ฉันกำลังทำระบบปฏิบัติการ (ฟรี) (แค่งานอดิเรกไม่ใหญ่และเป็นมืออาชีพอย่าง gnu) สำหรับโคลนนิ่ง AT 386 (486) ตัว สิ่งนี้ได้ทำการหมักมาตั้งแต่เดือนเมษายนและเริ่มเตรียมพร้อมแล้ว ฉันต้องการความคิดเห็นใด ๆ เกี่ยวกับสิ่งที่ผู้คนชอบ / ไม่ชอบใน minix เพราะระบบปฏิบัติการของฉันคล้ายกับมัน (รูปแบบทางกายภาพเดียวกันของระบบไฟล์ (เนื่องจากเหตุผลเชิงปฏิบัติ) เหนือสิ่งอื่นใด)
ขณะนี้ฉันได้ย้ายพอร์ตทุบตี (1.08) และ gcc (1.40) และสิ่งต่าง ๆ ดูเหมือนจะใช้ได้ นี่ก็หมายความว่าฉันจะได้รับบางสิ่งบางอย่างในทางปฏิบัติภายในไม่กี่เดือนและฉันอยากจะรู้ว่าคุณลักษณะส่วนใหญ่ที่คนต้องการ ข้อเสนอแนะใด ๆ ยินดีต้อนรับ แต่ฉันจะไม่สัญญาว่าจะใช้พวกเขา🙂
Linus (torvalds@kruuna.helsinki.fi)
PS ใช่ - ไม่มีโค้ด minix ใด ๆ และมี fs แบบมัลติเธรด มันไม่สามารถป้องกันได้ (ใช้การสลับงาน 386 ฯลฯ ) และอาจจะไม่สนับสนุนสิ่งอื่นใดนอกจาก AT-harddisks เพราะนั่นคือทั้งหมดที่ฉันมี :-(
ฉันสร้างไฟล์ชื่อlinus.txtฉันวางเนื้อหาแล้วฉันเขียนในคอนโซล:
sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl
เอาออกจะเป็น:
1 7 i
2 5 to
3 5 like
4 5 it
5 5 and
6 4 minix
7 4 a
8 3 torvalds
9 3 of
10 3 helsinki
11 3 fi
12 3 any
13 2 would
14 2 won
15 2 what
16 ...
หากคุณต้องการเห็นภาพเพียง 20 คำแรก:
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | head -n 20
เป็นสิ่งสำคัญที่จะทราบว่าคำสั่งTR 'AZ' 'a-z'ไม่ suport UTF-8 ยังเพื่อที่ว่าในภาษาต่างประเทศ Apres คำว่าจะได้รับการแปลเป็น apres
หากคุณต้องการค้นหาคำเพียงคำเดียวคุณสามารถเพิ่ม grep ได้ในตอนท้าย:
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\sword_to_search_for$"
ในสคริปต์ชื่อsearch_freq :
#!/bin/bash
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\s$1$"
ต้องเรียกใช้สคริปต์:
search_freq word_to_search_for
sed: -e expression #2, char 7: unterminated
s 'command` เช่นนี้นับทุกคำใช่มั้ย แต่ OP ถามเพียงอันเดียว คำอธิบายเล็กน้อยก็น่าจะดี
ขึ้นอยู่กับว่าคุณต้องการจับคู่คำในคีย์หรือในค่าของข้อมูล JSON คุณมีแนวโน้มที่จะต้องการดึงเฉพาะคีย์หรือค่าจากข้อมูลเท่านั้น ไม่เช่นนั้นคุณอาจนับคำได้หลายครั้งเกินไปหากคำนั้นเป็นทั้งคีย์และค่า
ในการแยกคีย์ทั้งหมด:
jq -r '..|objects|keys[]' <file.json
สิ่งนี้เป็นการทดสอบซ้ำว่าสิ่งปัจจุบันเป็นวัตถุหรือไม่และจะแยกกุญแจออกหรือไม่ ผลลัพธ์จะเป็นรายการของคีย์หนึ่งรายการต่อบรรทัด
ในการแยกค่าทั้งหมด:
jq -r '..|scalars' <file.json
สิ่งนี้ทำงานในลักษณะที่คล้ายกัน แต่มีขั้นตอนน้อยกว่า
จากนั้นคุณสามารถไพพ์เอาต์พุตข้างต้นผ่านgrep -c 'PATTERN'
(เพื่อจับคู่รูปแบบบางอย่างกับคีย์หรือค่า) หรือgrep -c -w -F 'WORD'
(เพื่อจับคู่คำในคีย์หรือค่า) หรือgrep -c -x -F 'WORD'
(เพื่อจับคู่คีย์หรือค่าที่สมบูรณ์) หรือคล้ายกันเพื่อ ทำการนับของคุณ
ฉันมี json กับสิ่งนี้: "number":"OK","number":OK"
ทำซ้ำหลายครั้งในหนึ่งบรรทัด
เคาน์เตอร์ "ตกลง" เรียบง่ายของฉัน:
sed "s|,|\n|g" response | grep -c OK
ฉันใช้คำสั่ง awk ด้านล่างเพื่อค้นหาจำนวนครั้งที่เกิดขึ้น
ไฟล์ตัวอย่าง
cat file1
praveen ajay
praveen
ajay monkey praveen
praveen boy praveen
คำสั่ง:
awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'
เอาท์พุต
awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'
5
awk '{sum+=gsub("praveen","")} END {print sum+0}'
หรือเพียงแค่
{ "key": "the key" }
ควรนับสตริงkey
หนึ่งหรือสองครั้ง