grep을 사용하여 디렉토리의 모든 파일에서 모든 단어의 발생 횟수를 계산하는 방법은 무엇입니까? 그러나 단어당 개수는 파일당 한 번만 증가합니다.

grep을 사용하여 디렉토리의 모든 파일에서 모든 단어의 발생 횟수를 계산하는 방법은 무엇입니까? 그러나 단어당 개수는 파일당 한 번만 증가합니다.

비슷한 질문을 했는데 사람들이 내 질문을 오해했습니다. 단어 수는 파일당 단어당 한 번만 증가하여 각 단어의 목록을 생성하는 방법을 묻습니다.

예를 들어, 10개의 파일이 있는 디렉토리가 있고 bash 명령을 사용하여 파일에 나타나는 단어 수에 따라 1-10 사이의 값을 가진 단어 목록을 생성하려고 합니다.

10 The
10 and
8 bash
7 command
6 help....

등.

나는 이미 단일 단어를 검색한다는 것을 알고 있지만 grep -l word *| wc -l모든 단어의 목록을 만들고 싶습니다.

tr '[A-Z]' '[a-z]' | tr -d '[:punct:]'대문자로 단어를 반복하지 않고 구두점을 제거하는 것과 결합하는 방법이 있습니까 ?

답변1

여기서는 Perl을 사용하겠습니다.

perl -T -lne '
  for (/\w+/g) {$count{lc $_}->{$ARGV}=undef}
  END {print "$_: " . keys %{$count{$_}} for keys %count}' ./*

$count{word}이는 키가 발견된 파일의 이름인 해시에 대한 참조인 해시를 구성합니다 word(그리고 우리가 신경 쓰지 않는 값은 여기에 설정됩니다 undef).

마지막으로 각 해시(즉, 발견된 각 단어)에 대한 요소 수(즉, 파일 수)만 계산합니다.

답변2

방금 원본봤는데여기에 대답하세요작성자: @Mehmet 관련 없는 콘텐츠를 검색하는 동안 작동하기는 하지만 매우 비효율적이며 모든 파일의 모든 고유 단어를 얻으려면 각 파일을 다시 읽어야 한다는 사실을 발견했습니다! @Jeff의 두 번째 답변은 매우 복잡하며 설명에도 불구하고 최악의 부분은 죄로 고통 받고 있다는 것입니다 cat file |!

모든 데이터에 대해 하나의 패스만 필요하며 이전 답변을 효율적으로 결합하여 공식화할 수 있습니다.

find . -maxdepth 1 -type f -print |
while read file; do
    egrep -h -o "[[:alnum:]][[:alnum:]_-]*" "$file" |
    tr '[A-Z]' '[a-z]' |
    sed "s|^|$file\||"
done |
sort -t '|' -k 2 |
uniq |
awk -F '|' '{
    if (lw != $2) {
        print fc " " lw;
        fc = 0;
    }
    lw = $2;
    fc++;
}'

파일 이름에 경로가 포함되거나 공백이 포함된 경우 필드 구분 기호 선택이 중요합니다. 이 문자를 선택한 |이유는 이 문자가 인쇄된 단어의 일부가 되어서는 안 되고 egrep파일이나 디렉터리 이름에 나타날 가능성이 거의 없기 때문입니다.

답변3

이렇게 하면 모든 파일에서 모든 단어를 가져와서 정렬하고 고유한 단어를 얻은 다음 단어를 반복하고 해당 단어가 나타나는 파일 수를 계산해야 합니다.

# find all words from all files within the directory
grep -o -h -E '\w+' directory/*|sort -u | \
while read word;
do
        # iterate through each word and find how many files it occurs
        c=`grep -l "$word" directory/*|wc -l`
        echo "$c $word";
done

답변4

디렉터리의 각 파일을 개별적으로 처리하는 방법은 다음과 같습니다.

for f in yourdirectory/*; do cat "$f" |

다음은 텍스트 데이터에서 단어를 제외한 모든 항목을 필터링하는 방법입니다.

sed 's/\.$//;s/\.\([^0-9]\)/\1/g;s/[][(),;:?!]//g' | tr [A-Z] [a-z] |

그러나 귀하의 접근 방식도 마찬가지로 효과적일 수 있습니다. (하이픈으로 연결된 단어에서 하이픈을 제거하거나 약어에서 아포스트로피를 제거하지 않도록 주의하고 싶습니다.)

어느 쪽이든 아래를 진행하세요.

tr -s ' ' '\012' | sort -u ; done |

그러면 파일당 단어 목록이 생성되므로 지금은 다음과 같습니다.

sort | uniq -c

가장 빈번한 것부터 가장 낮은 것 순으로 목록을 원할 경우 를 추가하면 됩니다 |sort -nr.

입력 데이터에 따라 {}위의 목록 과 같이 구두점을 추가해야 할 수도 있습니다 .sed

관련 정보