비슷한 질문을 했는데 사람들이 내 질문을 오해했습니다. 단어 수는 파일당 단어당 한 번만 증가하여 각 단어의 목록을 생성하는 방법을 묻습니다.
예를 들어, 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