it-swarm-vi.com

Làm cách nào để tôi đếm số lần xuất hiện của một từ trong tệp văn bản với dòng lệnh?

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 đó?

45
mythz
$ tr ' ' '\n' < FILE | grep Word | wc -l

Trong đó 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 phần wc bằng cách sử dụng phần -c tùy chọn của grep:

$ tr ' ' '\n' < FILE | grep -c Word

Các -c tùy chọn được xác định 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 (dưới dạng dấu phân cách) để thay thế. Ví dụ: các bộ phận thay thế tr

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 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 đầu/cuối dòng:

grep -c '^Word$'

Tương đương với các dấu bắt đầu/kết thúc Word, trong ngữ cảnh của chúng tôi:

grep -c '\<Word\>'
48
maxschlepzig

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.

\< Khẳng định bắt đầu một từ và \> Khẳng định sự kết thúc của một từ (tương tự như \b) Của Perl, vì vậy điều này đảm bảo rằng bạn không khớp với một chuỗi trong giữa một từ.

Ví dụ,

$ python -c 'nhập cái này' | grep '\ <one \>' [.__.] Nên có một- và tốt nhất là chỉ 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 \>' [.__.]mộtmộtmột$ python -c 'nhập cái này' | grep -o '\ <one \>' | wc -l [.__.] 3 [.__.]
25
ephemient

Thật không may 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, đó là một giải pháp thanh lịch và khá trực quan; nhưng the GNU mọi người vẫn đang suy nghĩ.

11
tripleee
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:

  1. Thay thế tất cả các ký tự không chữ và số với một khoảng trắng.
  2. Tất cả các ngắt dòng cũng được chuyển đổi thành không gian.
  3. Giảm tất cả nhiều khoảng trống thành một khoảng trống
  4. Tất cả các không gian bây giờ được chuyển đổi để ngắt dòng. Mỗi từ trong một dòng.
  5. Dịch tất cả các từ sang chữ thường để tránh 'Xin chào' và 'xin chào' thành các từ khác nhau
  6. Sắp xếp văn bản
  7. Đếm và loại bỏ các dòng bằng nhau
  8. Sắp xếp ngược lại để đếm những từ thường xuyên nhất
  9. Thêm một số dòng cho mỗi Word để biết toàn bộ vị trí của Word

Ví dụ: nếu tôi muốn phân tích thông điệp Linus Torvald đầu tiên:

Từ: [email protected] (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: <[email protected]> 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 386 (486) AT nhái. Điều này đã được sản xuất từ ​​tháng tư, và Tôi đã bắt đầu sẵn sàng. Tôi muốn mọi phản hồi 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 phần nào (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).

Hiện tại Iveve đã 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 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 muốn. Mọi lời đề nghị đều được chào đón, nhưng tôi đã thắng Lời hứa tôi sẽ thực hiện chúng ????

Linus ([email protected])

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

Điều quan trọng cần lưu ý là lệnh tr 'AZ' 'a-z' không hỗ trợ UTF-8 --- (chưa , do đó, bằng tiếng nước ngoài, từ APRÈS sẽ được dịch là aprÈs.

Nếu bạn chỉ muốn tìm kiếm sự xuất hiện của một Word, 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 tập lệnh có tên 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
7
Roger Borrell

Tùy thuộc vào việc bạn muốn khớp Word trong các khóa hay 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ể dẫ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 với Word 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ự, để thực hiện việc đếm của bạn.

3
Kusalananda

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

0
khazad-dum_miner

Sử dụng grep -c bạn sẽ chỉ đếm các dòng, một dòng có thể có nhiều lần xuất hiện của Word.

Điều này sẽ làm điều đó:

grep -o Word foo|wc -l
0
Ramiro Velazquez