Tôi có một tệp JSON lớn nằm trên một dòng và tôi muốn sử dụng dòng lệnh để có thể đếm số lần xuất hiện của một từ trong tệp. Làm thế nào tôi có thể làm điều đó?
Tôi có một tệp JSON lớn nằm trên một dòng và tôi muốn sử dụng dòng lệnh để có thể đếm số lần xuất hiện của một từ trong tệp. Làm thế nào tôi có thể làm điều đó?
Câu trả lời:
$ tr ' ' '\n' < FILE | grep WORD | wc -l
Khi tr
thay thế khoảng trắng bằng dòng mới, grep
lọc tất cả các dòng kết quả khớp với WORD và wc
đếm các dòng còn lại.
Người ta thậm chí có thể lưu wc
phần bằng cách sử dụng -c
tùy chọn của grep:
$ tr ' ' '\n' < FILE | grep -c WORD
Các -c
tùy chọn được định nghĩa bởi POSIX.
Nếu không đảm bảo rằng có khoảng trắng giữa các từ, bạn phải sử dụng một số ký tự khác (như dấu phân cách) để thay thế. Ví dụ các tr
bộ phận thay thế là
tr '"' '\n'
hoặc là
tr "'" '\n'
nếu bạn muốn thay thế dấu ngoặc kép hoặc đơn. Tất nhiên, bạn cũng có thể sử dụng tr
để thay thế nhiều ký tự cùng một lúc (nghĩ các loại khoảng trắng và dấu chấm câu khác nhau).
Trong trường hợp bạn cần đếm WORD nhưng không phải tiền tốWORD, WORDsuffix hoặc tiền tốWORDsuffix, bạn có thể đặt mẫu WORD trong các điểm đánh dấu bắt đầu / cuối dòng:
grep -c '^WORD$'
Tương đương với các từ bắt đầu / kết thúc, trong ngữ cảnh của chúng tôi:
grep -c '\<WORD\>'
tr
lệnh thực hiện công việc thay vì đề xuất các ví dụ sẽ không bao giờ hoạt động trong mọi tình huống. Nó cũng sẽ khớp với các từ có chứa từ bạn đang tìm kiếm. Các grep -o '\<WORD\>' | wc -l
giải pháp là cao hơn nhiều so.
Với GNU grep, điều này hoạt động: grep -o '\<WORD\>' | wc -l
-o
in từng phần phù hợp của từng dòng trên một dòng riêng biệt.
\<
xác nhận bắt đầu của một từ và \>
khẳng định kết thúc của một từ (tương tự như của Perl \b
), vì vậy điều này đảm bảo rằng bạn không khớp một chuỗi ở giữa một từ.
Ví dụ,
$ python -c 'nhập cái này' | grep '\ <một \>' Nên có một - và tốt nhất là chỉ có một cách rõ ràng để làm điều đó. Không gian tên là một ý tưởng tuyệt vời - hãy làm nhiều hơn nữa! $ python -c 'nhập cái này' | grep -o '\ <one \>' one one one $ python -c 'nhập cái này' | grep -o '\ <một \>' | wc -l 3
grep -wo WORD | wc -l
Thật không may, điều này không hoạt động với GNU coreutils
.
grep -o -c WORD file
Nếu nó hoạt động trên nền tảng của bạn, thì đó là một giải pháp thanh lịch và khá trực quan; nhưng những người GNU vẫn đang suy nghĩ.
grep
có lỗi ở đây. Không rõ POSIX là gì về ngữ nghĩa của việc kết hợp -c
và -o
nên nó không phải là di động. Cảm ơn các bình luận; Tôi đã cập nhật câu trả lời này.
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
Lệnh này thực hiện như sau:
Ví dụ: nếu tôi muốn phân tích thông điệp Linus Torvald đầu tiên:
Từ: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) Nhóm tin: comp.os.minix Chủ đề: Bạn muốn thấy gì nhất trong minix? Tóm tắt: cuộc thăm dò nhỏ cho hệ điều hành mới của tôi ID tin nhắn: <1991Aug25.205708.9541@klaava.Helsinki.FI> Ngày: 25 tháng 8 91 20:57:08 GMT Tổ chức: Đại học Helsinki
Xin chào mọi người ngoài kia bằng cách sử dụng minix -
Tôi đang làm một hệ điều hành (miễn phí) (chỉ là một sở thích, sẽ không lớn và chuyên nghiệp như gnu) cho các bản sao AT (486) AT. Điều này đã được ủ từ tháng tư, và bắt đầu sẵn sàng. Tôi muốn bất kỳ phản hồi nào về những thứ mọi người thích / không thích trong minix, vì HĐH của tôi giống với nó một chút (cùng bố cục vật lý của hệ thống tệp (vì lý do thực tế) trong số những thứ khác).
Tôi hiện đã chuyển bash (1.08) và gcc (1.40) và mọi thứ dường như hoạt động. Điều này ngụ ý rằng tôi sẽ nhận được một cái gì đó thiết thực trong vòng một vài tháng và tôi muốn biết những tính năng mà hầu hết mọi người sẽ muốn. Mọi lời đề nghị đều được chào đón, nhưng tôi sẽ không hứa sẽ thực hiện chúng
Linus (torvalds@kruuna.helsinki.fi)
Tái bút Có - nó không có bất kỳ mã minix nào và nó có fs đa luồng. Nó KHÔNG đáng tin cậy (sử dụng chuyển đổi tác vụ 386, v.v.) và có lẽ nó sẽ không bao giờ hỗ trợ bất cứ thứ gì ngoài AT-harddisks, vì đó là tất cả những gì tôi có :-(.
Tôi tạo một tệp có tên linus.txt , tôi dán nội dung và sau đó tôi viết trong bảng điều khiển:
sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl
Đặt ra sẽ là:
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 ...
Nếu bạn muốn hình dung chỉ 20 từ đầu tiên:
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
Quan trọng là phải lưu ý rằng lệnh tr 'AZ' 'a-z' không suport UTF-8 chưa , do đó bằng tiếng nước ngoài các Apres từ sẽ được dịch là Apres.
Nếu bạn chỉ muốn tìm kiếm sự xuất hiện của một từ, bạn có thể thêm một grep ở cuối:
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$"
Trong một tập lệnh gọi là 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$"
Kịch bản phải được gọi:
search_freq word_to_search_for
sed: -e expression #2, char 7: unterminated
s 'lệnh`, điều này cũng đếm tất cả các từ, phải không? Nhưng OP chỉ hỏi một người cụ thể. Ngoài ra một chút giải thích sẽ tốt đẹp.
Tùy thuộc vào việc bạn muốn khớp từ trong các khóa hoặc trong các giá trị của dữ liệu JSON, bạn có thể muốn trích xuất chỉ các khóa hoặc chỉ các giá trị từ dữ liệu. Nếu không, bạn có thể đếm một số từ quá nhiều lần nếu chúng xuất hiện dưới dạng cả khóa và giá trị.
Để giải nén tất cả các khóa:
jq -r '..|objects|keys[]' <file.json
Điều này đệ quy kiểm tra xem vật hiện tại có phải là một đối tượng hay không và nếu có, nó sẽ trích xuất các khóa. Đầu ra sẽ là một danh sách các khóa, mỗi khóa một dòng.
Để trích xuất tất cả các giá trị:
jq -r '..|scalars' <file.json
Điều này hoạt động theo cách tương tự, nhưng có ít bước hơn.
Sau đó, bạn có thể chuyển đầu ra của phần trên qua grep -c 'PATTERN'
(để khớp một số mẫu với các khóa hoặc giá trị) hoặc grep -c -w -F 'WORD'
(để khớp một từ trong các khóa hoặc giá trị) hoặc grep -c -x -F 'WORD'
(để khớp với một khóa hoặc giá trị hoàn chỉnh) hoặc tương tự, với đếm của bạn
Tôi có json với một cái gì đó như thế này: "number":"OK","number":OK"
lặp đi lặp lại nhiều lần trong một dòng.
Bộ đếm "OK" đơn giản của tôi:
sed "s|,|\n|g" response | grep -c OK
tôi đã sử dụng lệnh awk dưới đây để tìm số lần xuất hiện
tập tin ví dụ
tập tin mèo1
praveen ajay
praveen
ajay monkey praveen
praveen boy praveen
chỉ huy:
awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'
đầu ra
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" }
nên đếm chuỗikey
một hoặc hai lần hay không.