как посчитать общее количество слов в файле?

18

Я ищу команду для подсчета количества всех слов в файле. Например, если файл такой,

today is a 
good day

тогда это должно напечатать 5, так как там есть 5слова.

Ричард
источник
7
Ты пробовал wc -w $FILE?
don_crissti

Ответы:

39

Команда 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
SLM
источник
1
Обратите внимание, что слова для wc -wне имеют того же определения, что и для GNU grep -w. К wcслову относится последовательность из одного или нескольких непробельных символов ( [:space:]класс символов в текущей локали). Например , foo,barи foo bar(с неразрывным пробелом) каждое один слово.
Стефан Шазелас
7

Я придумал это просто для числа:

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

5

Мне тоже нравится wc -w < [file]подход

Наконец, для хранения только количества слов в переменной вы можете использовать следующее:

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

Это позволяет вам элегантно пропустить имя файла.

Майкл Даррант
источник
14
wc -w < "$file"просто номер.
Стефан Шазелас
3

Лучшее решение - использовать 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.

cuonglm
источник
13
Почему это лучше, чем туалет?
Спарр
2
@Sparr с одной стороны, потому что, к моему большому удивлению, кажется, что это намного быстрее. Я попробовал это на текстовом файле с 141813504 словами и wcзанял ~ 14сек, в то время как Perl занял ~ 5сек!
Terdon
3
Я думаю, что «большая» проблема - это ответ, который зависит от Perl, и я никогда не был большим поклонником такой зависимости. Если бы вопрос был о производительности, это было бы другое дело.
Майкл Даррант
5
Обратите внимание , что на это подобно исключением того, что ведущие пробельные производит нулевое первое поле. Это различие даст вам одно дополнительное слово (то есть нулевое первое поле) для каждой ссылки на строку . Поэтому используйте другой способ для файла, созданного так: ваш однострочный отчет сообщает 3 слова. split/\s+/split(' ') (split(" ", $_))echo -e "unix\n linux" > testfile
don_crissti
1
Ваше время показывает, что wc работает быстрее (это имеет значение для пользователя и sys). С LC_ALL = C wcбудет значительно быстрее, как и с PERLIO=:utf8, perlбудет значительно медленнее.
Стефан Шазелас
3

Давайте использовать 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

Здесь указана частота каждого слова, встречающегося в предоставленном файле. Я знаю, что это не то, что вы просили, но лучше! Если вы хотите увидеть вхождения вашего слова, вы можете просто сделать это:

$ cat your_file.txt | wordfrequency | grep yourword

Я даже добавил эту функцию в моей .dotfiles


Источник: AWK-опека Руби

Sheharyar
источник
Он считает слова, так что это достаточно хорошо для меня! :-)
Aggsol
3

В 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

Сравнение количества:

  • Запуск сценария сам по себе, дает мне 76 слов.
  • Пример в Perl от @cuonglm дает 31.
  • Использование wcдает 28.

Для справки, POSIX vi говорит:

В локали POSIX vi распознает пять видов слов:

  1. Максимальная последовательность букв, цифр и подчеркиваний, разделенных на обоих концах:

    • Символы, отличные от букв, цифр или подчеркиваний

    • Начало или конец строки

    • Начало или конец буфера редактирования

  2. Максимальная последовательность символов, кроме букв, цифр, символов подчеркивания или символов, разделенных на обоих концах:

    • Буква, цифра, подчеркивание
    • <blank> персонажи
    • Начало или конец строки
    • Начало или конец буфера редактирования
  3. Одна или несколько последовательных пустых строк

  4. Первый символ в буфере редактирования

  5. Последний не <newline>в буфере редактирования

Томас Дики
источник