명령 줄을 사용하여 텍스트 파일에서 단어의 발생 횟수를 어떻게 계산합니까?


43

한 줄에 큰 JSON 파일이 있고 파일에서 단어의 발생 횟수를 계산할 수 있도록 명령 줄을 사용하고 싶습니다. 어떻게해야합니까?


단어가 JSON 데이터의 키와 값 모두에서 일치해야하는지, 즉 { "key": "the key" }문자열을 key한 번 또는 두 번 계산 해야하는지 확실하지 않습니다 .
Kusalananda

답변:


45
$ tr ' ' '\n' < FILE | grep WORD | wc -l

tr공백을 개행 문자로 바꾸는 경우 grepWORD와 일치하는 모든 결과 행을 필터링 wc하고 나머지 행을 계산합니다.

grep 옵션을 wc사용하여 부품을 저장할 수도 있습니다 -c.

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

-c옵션은 POSIX에 의해 정의됩니다.

단어 사이에 공백이 있다고 보장되지 않으면 다른 문자 (구분 기호로)를 바꿔야합니다. 예를 들어 대체 tr부품은

tr '"' '\n'

또는

tr "'" '\n'

큰 따옴표 나 작은 따옴표를 바꾸려면 물론 tr여러 문자를 한 번에 바꾸는 데 사용할 수도 있습니다 (다른 종류의 공백과 문장 부호를 생각하십시오).

접 두부 WORD, WORDsuffix 또는 prefixWORDsuffix가 아닌 WORD를 계산해야하는 경우 WORD 패턴을 시작 / 끝 줄 표시 자로 묶을 수 있습니다.

grep -c '^WORD$'

다음과 같은 맥락에서 단어 시작 / 끝 마커와 같습니다.

grep -c '\<WORD\>'

공백이없는 경우, 즉 필드 이름이 따옴표로 묶이면 어떻게됩니까? 예 : "field"
mythz

@ mythz : 그런 다음 따옴표를 줄 바꿈으로 tr로 바꿉니다. 답변을 업데이트하겠습니다.
maxschlepzig

1
이 답변은 여러 가지면에서 부정확합니다. 모호 tr합니다. 모든 상황에서 결코 작동하지 않는 예제를 제안하는 대신 작업을 수행 하는 명령을 수행하는 방법을 설명해야 합니다. 또한 찾고있는 단어가 포함 된 단어와 일치합니다. grep -o '\<WORD\>' | wc -l솔루션은 훨씬 우수합니다.
sam hocevar

1
@Sam, 검색된 단어가 'WORD'또는 '\ <WORD \>'와 같이 검색되어야하는 경우 질문은 일종의 열린 상태로 남습니다. 두 가지 방법으로 읽을 수 있습니다. 두 번째 방법으로 만 읽고 두 번째 방법으로 만 읽더라도 내 대답은 한 가지 방법으로 만 잘못됩니다. ;) 그리고 'grep -o'솔루션은 POSIX에 의해 지정되지 않은 -o 옵션을 지원하는 경우에만 우수합니다 ... 글쎄, tr을 사용하는 것이 이국적인 것으로 생각하지 않습니다. 막연한 ...
maxschlepzig 21:01에

1
@ Kusalananda, 여전히 발생합니다. 그러나 이러한 하위 문자열 일치를 계산하지 않으려면 내 답변의 마지막 단락과 이전 주석을 읽으십시오.
maxschlepzig

24

GNU grep을 사용하면 다음과 같이 작동합니다. grep -o '\<WORD\>' | wc -l

-o 각 줄의 일치하는 각 부분을 별도의 줄에 인쇄합니다.

\<단어의 시작을 주장하고 단어 \>의 끝을 주장합니다 (Perl과 유사 \b). 이렇게하면 단어 중간에있는 문자열과 일치하지 않습니다.

예를 들어

$ python -c '가져 오기'| grep '\ <one \>'
이 있어야 하나 만을 바람직하고 - 하나 그것을 할 --obvious 방법.
네임 스페이스는 훌륭한 아이디어 중 하나입니다. 더 많은 것을 해보자!
$ python -c '가져 오기'| 그렙 -o '\ <하나 \>'
 하나 
하나 
하나 개 
$ 파이썬 -c '이 가져올'| grep -o '\ <one \>'| 화장실 -l
삼

1
아니면 그냥grep -wo WORD | wc -l
스테판 Chazelas

10

불행히도 GNU 에서는 작동하지 않습니다coreutils .

grep -o -c WORD file

플랫폼에서 작동한다면 우아하고 직관적 인 솔루션입니다. 그러나 GNU 사람들은 여전히 ​​생각하고 있습니다.


2
내 나쁜, 버그는 여전히 열려 있습니다 : savannah.gnu.org/bugs/?33080
tripleee

1
이것이 가장 우아했을 것입니다
MasterScrat

이것은 나를 위해 일했다!
ThisaruG

이것은 잘못이다. 패턴 WORD가있는 줄 수를 계산합니다. OP는 총 발생 횟수를 원합니다.
Pierre B

@PierreB 이것이 GNU grep에 버그가 있다고 말하는 이유 입니다. 결합의 의미 어떤 POSIX에서 분명하지 않다 -c그리고 -o이 현재 휴대용되지 않도록해야한다. 의견 주셔서 감사합니다; 이 답변을 업데이트했습니다.
tripleee

7
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 

이 명령은 다음을 수행합니다.

  1. 영숫자가 아닌 모든 문자를 공백으로 대체하십시오.
  2. 모든 줄 바꿈도 공백으로 변환됩니다.
  3. 모든 여러 공백을 하나의 공백으로 줄입니다.
  4. 모든 공백이 줄 바꿈으로 변환되었습니다. 한 줄에있는 각 단어.
  5. 'Hello'와 'hello'가 다른 단어가되지 않도록 모든 단어를 소문자로 번역
  6. 텍스트 정렬
  7. 같은 줄을 세고 제거
  8. 가장 빈번한 단어를 계산하기 위해 역순으로 정렬
  9. 전체에서 단어 위치를 알기 위해 각 단어에 줄 번호를 추가하십시오.

예를 들어 첫 번째 Linus Torvald 메시지를 분석하려는 경우 :

From : torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) 뉴스 그룹 : comp.os.minix 주제 : Minix에서 가장보고 싶은 것은 무엇입니까? 요약 : 새 운영 체제에 대한 소규모 설문 조사 Message-ID : <1991Aug25.205708.9541@klaava.Helsinki.FI> 날짜 : 91 8 월 91 일 20:57:08 GMT 조직 : 헬싱키 대학

안녕하십니까?

386 (486) AT 클론에 대해 (무료) 운영 체제 (단지 취미는 gnu와 같이 크고 전문적이지 않습니다)를하고 있습니다. 이것은 4 월부터 양조되어 준비를 시작하고 있습니다. OS가 사람들과 다소 비슷하기 때문에 (실제적인 이유로 파일 시스템의 물리적 레이아웃과 유사) Minix에서 사람들이 좋아하거나 싫어하는 것에 대한 피드백을 원합니다.

현재 bash (1.08) 및 gcc (1.40)을 이식했으며 작동하는 것 같습니다. 이것은 몇 달 안에 실용적인 것을 얻게 될 것이며 대부분의 사람들이 원하는 기능을 알고 싶습니다. 모든 제안은 환영하지만 구현할 것이라고 약속하지는 않습니다. 🙂

리누스 (torvalds@kruuna.helsinki.fi)

추신. 그렇습니다 – 모든 미니 코드가 없으며 멀티 스레드 fs가 있습니다. 그것은 (386 작업 전환 등을 사용하여) protable하지 않으며 아마 AT 하드 디스크 이외의 다른 것을 지원하지 않을 것입니다.

linus.txt 라는 파일을 만들고 내용을 붙여 넣은 다음 콘솔에 씁니다.

sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

결과는 다음과 같습니다.

 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        ...

처음 20 개 단어 만 시각화하려면 다음을 수행하십시오.

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

tr 'AZ' 'a-z' 명령 은 아직 UTF-8을 지원하지 않으므로 외국어에서는 APRÈS라는 단어가 aprÈs로 번역됩니다.

한 단어의 발생 만 검색하려는 경우 끝에 grep을 추가 할 수 있습니다.

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$"

스크립트는 다음과 같이 호출되어야합니다.

 search_freq word_to_search_for

sed: -e expression #2, char 7: unterminated s '명령, 이것도 모든 단어를 세지? 그러나 OP는 특정 질문 만했습니다. 또한 약간의 설명이 좋을 것입니다.
phk

실수를해서 죄송합니다. 나는 명령을 다시 작성하고 대답을 논평했다. 내 생각에, 그 질문에서, 그가 한 단어의 출현이나 빈도의 빈도를 알고 싶어한다는 것은 불가능합니다. 그러나 한 단어 만 얻으려면 끝에 grep을 추가 할 수 있습니다.
Roger Borrell

3

키의 단어 또는 JSON 데이터의 값과 일치하는지에 따라 키에서 데이터 만 추출하거나 데이터에서 값만 추출 할 수 있습니다. 그렇지 않으면 일부 단어가 키와 값으로 나타날 경우 단어를 너무 많이 계산할 수 있습니다.

모든 키를 추출하려면

jq -r '..|objects|keys[]' <file.json

이것은 현재 사물이 객체인지 여부를 재귀 적으로 테스트하고, 그렇다면 사물을 추출합니다. 출력은 한 줄에 하나씩 키 목록이됩니다.

모든 값을 추출하려면

jq -r '..|scalars' <file.json

이것은 비슷한 방식으로 작동하지만 단계가 적습니다.

그런 다음 위의 출력을 grep -c 'PATTERN'(키 또는 값과 일부 패턴과 일치 시키거나) 또는 grep -c -w -F 'WORD'( 키 또는 값 의 단어 와 일치시키기 위해 ) 또는 grep -c -x -F 'WORD'(완전한 키 또는 값과 일치시키기 위해) 또는 유사하게 당신의 계산을 수행합니다.


0

나는 다음과 같은 json을 가지고있다 : "number":"OK","number":OK"한 줄에 여러 번 반복했다.

간단한 "OK"카운터 :

sed "s|,|\n|g" response | grep -c OK


-1

awk 명령 아래에서 발생 횟수를 찾았습니다.

예제 파일

고양이 파일 1

praveen ajay 
praveen
ajay monkey praveen
praveen boy praveen

명령:

awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'

산출

awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'

5

아니면 그냥 awk '{sum+=gsub("praveen","")} END {print sum+0}'.
G-Man은

왜 내 대답에 투표를했는지 알려주세요
Praveen Kumar BS
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.