Tôi đang tìm kiếm một lệnh để đếm số lượng của tất cả các từ trong một tập tin. Chẳng hạn, nếu một tập tin như thế này,
today is a
good day
sau đó nó nên in 5
, vì có những 5
từ đó.
Tôi đang tìm kiếm một lệnh để đếm số lượng của tất cả các từ trong một tập tin. Chẳng hạn, nếu một tập tin như thế này,
today is a
good day
sau đó nó nên in 5
, vì có những 5
từ đó.
Câu trả lời:
Lệnh wc
aka. đếm từ có thể làm điều đó:
$ wc -w <file>
$ 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
wc -w
không có định nghĩa tương tự như đối với GNU grep -w
. Đối với wc
mộ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,bar
và foo bar
(với một không gian không phá vỡ) là mỗi một từ.
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.
wc -w < "$file"
cho CHỈ số.
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 wc
lệnh từ coreutils, tôi kiểm tra trong máy của mình, với tệp subst.c
trong nguồn bash 4.2.
time wc -w subst.c
real 0m0.025s
user 0m0.016s
sys 0m0.000s
Và
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
.
wc
mất ~ 14 giây trong khi Perl mất ~ 5 giây!
split
on /\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" > testfile
một-liner của bạn báo cáo 3 từ.
wc
sẽ nhanh hơn đáng kể, giống như với PERLIO=:utf8
, perl
sẽ chậm hơn đáng kể.
$ 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
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 vi
chươ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 wc
chỉ 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
vi
nhìn thấy ba từ ( thứ nhất và thứ hai cũng như dấu phẩy ngăn cách chúng), trong khi wc
nhì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
, tr
và wc
(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:
wc
cho 28.Để tham khảo, POSIX vi nói:
Trong ngôn ngữ POSIX, vi sẽ nhận ra năm loại từ:
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
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
Một hoặc nhiều dòng trống liên tiếp
Ký tự đầu tiên trong bộ đệm chỉnh sửa
Cái không cuối cùng
<newline>
trong bộ đệm chỉnh sửa
wc -w $FILE
chưa