매개변수로 전달된 모든 "n"개 파일에서 해당 파일에 속하는 각 단어의 발생 횟수를 어떻게 계산합니까?

매개변수로 전달된 모든 "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

답변1

나는 그것을 할 것이다:

#! /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

(이것은 각 파일에서 적어도 한 번 이상 발견된 단어 수만 제공합니다).

답변2

다음과 같이 명령줄에 제공된 파일 목록을 반복할 수 있습니다.

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도움이 될 수 있습니다.

답변3

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

관련 정보