Làm thế nào để đếm tổng số từ trong một tập tin?


Câu trả lời:


39

Lệnh wcaka. đếm từ có thể làm điều đó:

$ wc -w <file>

thí dụ

$ cat sample.txt
today is a 
good day


$ wc -w sample.txt
5 sample.txt


# just the number (thanks to Stephane Chazelas' comment)
$ wc -w < sample.txt
5

1
Lưu ý rằng lời cho wc -wkhông có định nghĩa tương tự như đối với GNU grep -w. Đối với wcmột từ là một chuỗi gồm một hoặc nhiều ký tự không phải khoảng trắng ( [:space:]lớp ký tự trong miền địa phương hiện tại). Ví dụ foo,barfoo bar(với một không gian không phá vỡ) là mỗi một từ.
Stéphane Chazelas

7

Tôi đã đưa ra điều này cho CHỈ số:

wc -w [file] | cut -d' ' -f1

5

Tôi cũng thích wc -w < [file]cách tiếp cận

Cuối cùng, để lưu trữ chỉ số từ trong một biến, bạn có thể sử dụng như sau:

myVar=($(wc -w /path/to/file))

Điều này cho phép bạn bỏ qua tên tệp một cách thanh lịch.


14
wc -w < "$file"cho CHỈ số.
Stéphane Chazelas

3

Giải pháp tốt hơn là sử dụng Perl:

perl -nle '$word += scalar(split(/\s+/, $_)); END{print $word}' filename

@Bernhard

Bạn có thể kiểm tra mã nguồn của wclệnh từ coreutils, tôi kiểm tra trong máy của mình, với tệp subst.ctrong nguồn bash 4.2.

time wc -w subst.c

real    0m0.025s
user    0m0.016s
sys     0m0.000s

time perl -nle '$word += scalar(split(" ", $_)); END{print $word}' subst.c

real    0m0.021s
user    0m0.016s
sys     0m0.004s

Tệp càng lớn, Perl càng hiệu quả đối với wc.


13
Tại sao điều này tốt hơn wc?
Sparr

2
@Sparr cho một điều bởi vì, với sự ngạc nhiên rất lớn của tôi, nó dường như nhanh hơn nhiều . Tôi đã thử nó trên một tệp văn bản với 141813504 từ và wcmất ~ 14 giây trong khi Perl mất ~ 5 giây!
terdon

3
Tôi nghĩ vấn đề 'lớn hơn' thực sự là một câu trả lời có sự phụ thuộc vào Perl và tôi không bao giờ là một fan hâm mộ lớn của sự phụ thuộc như vậy. Nếu câu hỏi là về hiệu suất sẽ là một điều khác.
Michael Durrant

5
Lưu ý rằng một spliton /\s+/giống như split(' ')ngoại trừ rằng bất kỳ khoảng trắng hàng đầu nào cũng tạo ra trường đầu tiên null. Sự khác biệt đó sẽ cung cấp cho bạn thêm một từ (trường đầu tiên null, nghĩa là) trên mỗi liên kết dòng . Vì vậy, sử dụng (split(" ", $_))khác cho một tập tin được tạo như thế này: echo -e "unix\n linux" > testfilemột-liner của bạn báo cáo 3 từ.
don_crissti

1
Thời gian của bạn cho thấy wc nhanh hơn (đó là người dùng và hệ thống lần quan trọng ở đó). Với LC_ALL = C, wcsẽ nhanh hơn đáng kể, giống như với PERLIO=:utf8, perlsẽ chậm hơn đáng kể.
Stéphane Chazelas

3

Hãy sử dụng 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

Điều này liệt kê tần suất của mỗi từ xuất hiện trong tệp được cung cấp. Tôi biết đó không phải là những gì bạn yêu cầu, nhưng nó tốt hơn! Nếu bạn muốn xem sự xuất hiện của từ của bạn, bạn chỉ có thể làm điều này:

$ cat your_file.txt | wordfrequency | grep yourword

Tôi thậm chí đã thêm chức năng này vào .dotfiles của mình


Nguồn: AWK-phường Ruby


Nó đếm từ, vì vậy nó là đủ tốt cho tôi! :-)
aggieol

3

Các wcđếm chương trình "chữ", nhưng những người không ví dụ các "chữ" mà nhiều người sẽ nhìn thấy khi họ kiểm tra một tập tin. Các vichương trình ví dụ sử dụng một biện pháp khác nhau của "chữ", phân chia ranh giới họ dựa trên các lớp nhân vật của mình, trong khi wcchỉ tính những điều ngăn cách bởi khoảng trắng . Hai biện pháp có thể hoàn toàn khác nhau. Xem xét ví dụ này:

first,second

vinhìn thấy ba từ ( thứ nhấtthứ hai cũng như dấu phẩy ngăn cách chúng), trong khi wcnhìn thấy một từ (không có khoảng trắng trên dòng đó). Có nhiều cách để đếm từ, một số ít hữu ích hơn những cách khác.

Trong khi Perl sẽ phù hợp tốt hơn để viết một bộ đếm cho các từ vi-phong cách, đây là một ví dụ nhanh sử dụng sed, trwc(vừa xách tay sử dụng kí tự xuống dòng đen ^M):

#!/bin/sh
in_words="[[:alnum:]_]"
in_punct="[][{}\\|:\"';<>,./?\`~!@#$%^&*()+=-]"
sed     -e "s/\($in_words\)\($in_punct\)/\1^M\2/g" \
        -e "s/\($in_punct\)\($in_words\)/\1^M\2/g" \
        -e "s/[[:space:]]/^M/g" \
        "$@" |
tr '\r' '\n' |
sed     -e '/^$/d' |
wc      -l

So sánh số lượng:

  • Chạy kịch bản trên chính nó, cho tôi 76 từ.
  • Ví dụ trong Perl của @cuonglm đưa ra 31.
  • Sử dụng wccho 28.

Để tham khảo, POSIX vi nói:

Trong ngôn ngữ POSIX, vi sẽ nhận ra năm loại từ:

  1. Một chuỗi tối đa các chữ cái, chữ số và dấu gạch dưới, được phân cách ở cả hai đầu bằng:

    • Các ký tự không phải là chữ cái, chữ số hoặc dấu gạch dưới

    • Đầu hoặc cuối của một dòng

    • Bắt đầu hoặc kết thúc bộ đệm chỉnh sửa

  2. Một chuỗi các ký tự tối đa khác với các chữ cái, chữ số, dấu gạch dưới hoặc ký tự, được phân cách ở cả hai đầu bằng:

    • Một chữ cái, chữ số, gạch dưới
    • <blank> nhân vật
    • Đầu hoặc cuối của một dòng
    • Bắt đầu hoặc kết thúc bộ đệm chỉnh sửa
  3. Một hoặc nhiều dòng trống liên tiếp

  4. Ký tự đầu tiên trong bộ đệm chỉnh sửa

  5. Cái không cuối cùng <newline>trong bộ đệm chỉnh sửa

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.