Шукаю команду для підрахунку кількості всіх слів у файлі. Наприклад, якщо такий файл,
today is a
good day
тоді він повинен надрукувати 5
, оскільки там є 5
слова.
Шукаю команду для підрахунку кількості всіх слів у файлі. Наприклад, якщо такий файл,
today is a
good day
тоді він повинен надрукувати 5
, оскільки там є 5
слова.
Відповіді:
Команда wc
ака. кількість слів може це зробити:
$ 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
не мають того самого визначення, що і для GNU grep -w
. Для wc
слова - це послідовність одного або декількох символів, що не містять пробілів ( [:space:]
клас символів у поточній мові). Наприклад, foo,bar
і foo bar
(з пробілом) - це одне слово.
Я придумав це ДІЙКІСТЬ номер:
wc -w [file] | cut -d' ' -f1
5
Мені також подобається wc -w < [file]
підхід
Нарешті, для зберігання лише кількості слів у змінній ви можете використовувати наступне:
myVar=($(wc -w /path/to/file))
Це дозволяє елегантно пропустити ім'я файлу.
wc -w < "$file"
ЗА ПОВЕРНЕНО число.
Краще рішення - використання Perl:
perl -nle '$word += scalar(split(/\s+/, $_)); END{print $word}' filename
@Bernhard
Ви можете перевірити вихідний код wc
команди з coreutils, який я перевіряю на своїй машині, з файлом subst.c
у джерелі 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
Чим більший файл, тим ефективніше Perl щодо wc
.
wc
взяв ~ 14 сек, тоді як Perl взяв ~ 5 сек!
split
на /\s+/
- це як split(' ')
виняток, що будь-який провідний пробіл виробляє нульове перше поле. Ця різниця дасть вам одне додаткове слово (нульове перше поле, тобто) за кожне посилання . Тож використовуйте (split(" ", $_))
інакше для файлу, створеного таким чином: echo -e "unix\n linux" > testfile
ваш однокласник повідомляє 3 слова.
wc
буде значно швидше, як і з PERLIO=:utf8
, perl
буде значно повільніше.
$ 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
Тут перерахована частота кожного слова, що зустрічається у наданому файлі. Я знаю, що це не те, про що ви просили, але краще! Якщо ви хочете побачити слова вашого слова, ви можете просто зробити це:
$ cat your_file.txt | wordfrequency | grep yourword
Я навіть додав цю функцію до своїх .dotfiles
Джерело: AWK-палатка Ruby
У wc
програмі підраховує «слова», але такими не є, наприклад , «слова» , що багато людей бачать , коли вони розглядають файл. Наприклад, vi
програма використовує іншу міру "слів", розмежовуючи їх на основі класів символів, при цьому wc
просто рахує речі, розділені пробілом . Два заходи можуть бути кардинально різними. Розглянемо цей приклад:
first,second
vi
бачить три слова ( перше і друге , а також кома, що розділяє їх), а wc
бачить одне (у цьому рядку немає пробілу). Існує багато способів підрахунку слів, деякі з них менш корисні, ніж інші.
У той час як Perl буде краще підходить для написання лічильник для слів ві-стилю, ось швидкий приклад використання sed
, tr
і wc
(помірно портативний , використовуючи літерні символи повернення каретки ^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
Порівняння підрахунків:
wc
дає 28.Для довідки, POSIX vi каже:
У локалі POSIX vi повинен розпізнавати п'ять видів слів:
Максимальна послідовність букв, цифр і підкреслень, розмежована на обох кінцях:
Символи, відмінні від букв, цифр чи підкреслення
Початок або кінець рядка
Початок або кінець буфера редагування
Максимальна послідовність символів, окрім букв, цифр, підкреслень чи символів, з обох кінців розміщена на:
- Буква, цифра, підкреслення
<blank>
символів- Початок або кінець рядка
- Початок або кінець буфера редагування
Один або кілька послідовних порожніх рядків
Перший символ у буфері редагування
Останній не
<newline>
в буфері редагування
wc -w $FILE
?