как подсчитать количество вхождений word в текстовый файл с помощью командной строки?

<p>у меня есть большой файл json, который находится в одной строке, и я хочу использовать командную строку, чтобы иметь возможность подсчитывать количество вхождений word в файл. как я могу это сделать?</p>

<pre><code>$ tr ' ' 'n' < file | grep word | wc -l где tr заменяет пробелы символами новой строки, grep фильтрует все результирующие строки, соответствующие word, а wc подсчитывает оставшиеся.можно даже сохранить часть wc, используя -c опция grep:$ tr ' ' '\n' < file | grep -c word </code></pre><p><code>-c</code> опция определяется posix.</p><p>если не гарантировано, что между словами есть пробелы, вы должны использовать какой-либо другой символ (как разделитель) для замены. например, альтернативные <code>tr</code> части</p><pre><code>tr '"' '\n' </code></pre><p>или</p><pre><code>tr "'" '\n' </code></pre><p>если вы хотите заменить двойные или одинарные кавычки. конечно, вы также можете использовать <code>tr</code> для одновременной замены нескольких символов (например, пробелы и знаки препинания).</p><p>если вам нужно посчитать word, а не префикс word, wordsuffix или prefixwordsuffix, вы можете заключить шаблон word в маркеры начала/конца строки:</p><pre><code>grep -c '^word$' что эквивалентно маркерам word-begin/end в нашем контексте:grep -c '' 

с gnu grep, это работает: <strong>grep -o '' | wc -l</strong>-o печатает каждую совпавшую часть каждой строки в отдельной строке.< утверждает начало word и > утверждает конец слова (аналогично perl b), так что это гарантирует, что вы не соответствуете строке в середине слова.например, $</b> python -c 'импортировать это' | grep '\ <one \>' там должно быть <b>один</b>- и желательно только <b>один</b> - очевидный способ сделать это. пространства имен <b>один</b> сигналят отличную идею - давайте сделаем больше таких! <b>$ python -c 'импортировать это' | grep -o ' <one >' один один один $</b> python -c 'импортировать это' | grep -o '\ <one \>' | wc -l 3 </pre>

<p>к сожалению <strong> это не работает </strong> с gnu <code>coreutils</code>.</p><pre><code>grep -o -c word file </code></pre><p>если он работает на вашей платформе, это элегантное и довольно интуитивное решение; но <a href="https://savannah.gnu.org/bugs/?33080">gnu люди все еще думают.</a> </p>

<pre><code>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 </code></pre><p>эта команда делает следующее:</p><ol> <li>замените все не алфавитно-цифровые символы пробелом.</li> <li>все разрывы строк также преобразуются в пробелы.</li> <li>уменьшает все несколько пробелов до одного пробела</li> <li>все пробелы теперь преобразуются в разрывы строк. каждое слово в строке.</li> <li>переводит все слова в нижний регистр, чтобы избежать "hello" и "hello", чтобы быть разными словами</li> <li>сортирует текст</li> <li>считает и удаляет равные линии</li> <li>сортирует в обратном порядке, чтобы посчитать самые частые слова</li> <li>добавьте номер строки к каждому слову, чтобы узнать о словесности в целом</li> </ol><p>например, если я хочу проанализировать первое сообщение линуса торвальда:</p><blockquote> <p>от: torvalds@klaava.helsinki.fi (линус бенедикт торвальдс) группы новостей: comp.os.minix тема: что бы вы хотели увидеть больше всего в minix? резюме: небольшой опрос для моей новой операционной системы. идентификатор сообщения: <1991aug25.205708.9541@klaava.helsinki.fi> дата: 25 августа, 91 20:57:08 gmt организация: университет хельсинки</p> <p>привет всем, кто использует minix -</p> <p>я делаю (бесплатную) операционную систему (просто хобби, она не будет большой и профессиональной, как gnu) для 386 (486) at клонов. это варилось с апреля, и начинает готовиться. я хотел бы получить какие-либо отзывы о вещах, которые людям нравятся/не нравятся в minix, поскольку моя ос чем-то напоминает это (такая же физическая структура файловой системы (по практическим причинам) среди прочего).</p> <p>в настоящее время я перенес bash (1.08) и gcc (1.40), и кажется, что все работает. это подразумевает, что я получу что-то практическое в течение нескольких месяцев, и я хотел бы знать, какие функции хотели бы получить большинство людей. любые предложения приветствуются, но я не обещаю, что буду их реализовывать ????</p> <p>линус (torvalds@kruuna.helsinki.fi)</p> <p>ps. да, он свободен от любого кода minix и имеет многопоточный fs. он не переносим (использует 386 переключений задач и т.д.) и, вероятно, никогда не будет поддерживать ничего, кроме жестких дисков at, поскольку это все, что у меня есть : <a href="http://www.pixelbeat.org/docs/coreutils\_i18n/">.</p> </blockquote><p>я создаю файл с именем <em> linus.txt </em>, я вставляю содержимое, а затем пишу в консоли:</p><pre><code>sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'a-z' 'a-z' | sort | uniq -c | sort -nr | nl </code></pre><p>результат будет:</p><pre><code> 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 ... </code></pre><p>если вы хотите визуализировать только первые 20 слов:</p><pre><code>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 </code></pre><p>важно отметить, что команда <em> tr 'az' 'a-z' </em> не поддерживает utf-8 --- (пока</a> , так что на иностранных языках слово après будет переведено как après.</p><p>если вы хотите искать только одно слово, вы можете добавить в конце команду grep:</p><pre><code>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$" в скрипте под названием  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$" </code></pre><p>сценарий должен называться:</p><pre><code> search\_freq word\_to\_search\_for </code></pre>

<p>в зависимости от того, хотите ли вы сопоставить word в ключах или в значениях данных json, вы, вероятно, захотите извлечь из данных только ключи или только значения. в противном случае вы можете посчитать некоторые слова слишком много раз, если они встречаются как ключи и значения.</p><p>чтобы извлечь все ключи:</p><pre><code>jq -r '..|objects|keys[]' <file.json </code></pre><p>это рекурсивно проверяет, является ли текущая вещь объектом, и, если это так, извлекает ключи. выводом будет список ключей, по одному на строку.</p><p>чтобы извлечь все значения:</p><pre><code>jq -r '..|scalars' <file.json </code></pre><p>это работает аналогичным образом, но имеет меньше шагов.</p><p>затем вы можете передать вывод выше через <code>grep -c 'pattern'</code> (для сопоставления некоторого шаблона с ключами или значениями) или <code>grep -c -w -f 'word'</code> (чтобы соответствовать <em>word</em> в ключах или значениях) или <code>grep -c -x -f 'word'</code> (чтобы соответствовать полный ключ или значение), или аналогичный, чтобы сделать ваш подсчет.</p>

<p>у меня есть json с чем-то вроде этого: <code>"number":"ok","number":ok"</code> повторяется несколько раз в одной строке.</p><p>мой простой счетчик "ок":</p><p><code>sed "s|,|\n|g" response | grep -c ok</code></p>

<p>с помощью <code>grep -c</code> вы будете считать только строки, одна строка может иметь много вхождений слова.</p><p>это сделало бы это:</p><pre><code>grep -o word foo|wc -l </code></pre>