Как подсчитать вхождения каждого слова, принадлежащего файлу, во все количество файлов `n`, переданных в качестве аргументов?

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

Я очень уверен, как подсчитать вхождения одного слова в отношении одного файла.

То есть, используя этот трюк:

$ tr ' ' '\n' < FILE | grep -c WORD 

Но я застреваю, когда доходит до n количества файлов.

Я новичок в программировании оболочки.

Это то, к чему я пришел:

 #!/bin/bash if [ $# -lt 2 ] then echo "Very less arguments bro." fi search_file=`tr '\n' ' ' < $1` # Make the first file in to a sequence of words. for other_file in "$@" do if [ $other_file = $1 ] then continue fi # Modify this file such that each space turns in to a newline tr ' ' '\n' < $other_file > new_temp_file for search_word in $search_file do word_freq=`grep -c $search_word new_temp_file` echo "Word=$search_word Frequency=$word_freq" done done 

3 Solutions collect form web for “Как подсчитать вхождения каждого слова, принадлежащего файлу, во все количество файлов `n`, переданных в качестве аргументов?”

Я сделаю:

 #! /bin/sh - # usage: wordcount <file-with-words-to-search-for> [<file>...] words=$(tr -s '[[:space:]]' '[\n*]' < "${1?No word list provided}" | grep .) [ -n "$words" ] || exit shift for file do printf 'File: %s\n' "$file" tr -s '[[:space:]]' '[\n*]' | grep -Fxe "$words" | sort | uniq -c | sort -rn done 

(который дает только количество слов, найденных по крайней мере один раз в каждом файле).

Вы можете перебирать список файлов в командной строке следующим образом:

 for file in "$@" do echo "Considering file ==> $file <==" done 

Ваш метод совпадения слов должен быть совершенно эффективным. Вы также можете искать вхождения слова, используя grep -o

 echo 'I can cry cryogenic tears when I scry my hands. Can you cry too?' | grep -o '\bcry\b' # \b marks a word boundary 

Проводя результат этого в wc -l , вы получите количество вхождений во входном потоке.

Использование $( ... ) позволяет интерполировать вывод команды в текст, используемый другим. Например

 echo "The date and time right now is $(date)" 

Нам нужна дополнительная работа, чтобы не искать первый файл, а вместо этого использовать это как список слов. Но, соединяя это, вы можете в итоге что-то вроде этого:

 wordfile="$1" wordlist=($(cat "$wordfile")) shift for file in "$@" do for word in "${wordlist[@]}" do # echo "$file: $word:" $(grep -o "\b${word}\b" "$file" | wc -l) # My way echo "$file: $word:" $(tr ' ' '\n' <"$file" | grep -c "$word") # Your way done done 

Это не очень эффективно, потому что для N слов он будет искать каждый файл N раз. Вы можете обнаружить, что grep -f здесь поможет.

 fgrep -cw 'word' file1 file2 ... fileN 

Это выведет следующее:

 file1:4 file2:16 

и так далее, по одной в каждой строке. Если это всего лишь общее количество всех файлов, сделайте следующее:

 echo "Total: $(( $(fgrep -cw 'word' file1 file2 ... fileN | awk -F: '{ print $NF" + " }') 0 ))" 

который будет выводить:

 Total: 20 
  • Использование sed для консолидации разностного вывода
  • grep -A с обратной совпадением распечатывает только несоответствие в поле после
  • Полосы пробелов после одиночных заглавных букв с sed
  • Сценарий для извлечения выбранных записей из файла bibtex
  • команда sed для добавления другого текста при множественном вводе строки
  • Как преобразовать данные с разделителями табуляции в данные с разделителями-запятыми?
  • Улучшить команду sed для замены первого экземпляра символа и всех следующих символов?
  • Отменить перемещение букв с помощью sed
  • Извлечь третью группу текста из разделителей диапазонов
  • Назначения значений двойной кавычки, хранящиеся в CSV?
  • Сопоставьте начало линии с чем-то там?
  • Linux и Unix - лучшая ОС в мире.