grep -c를 사용하여 총 발생 횟수를 계산하면 파일에서 문자열이 몇 번 발생하는지 찾는 데 유용합니다. 하지만 한 줄에 한 번만 각 항목을 계산합니다. 한 줄에 여러 번 발생하는 횟수를 계산하는 방법은 무엇입니까?

다음보다 더 우아한 것을 찾고 있습니다.

perl -e "$_ = <>; print scalar ( () = m/needle/g ), "\n"" 

댓글

  • grep가 지정되어 있음을 알고 있지만 ack를 사용하는 모든 사용자의 경우 대답은 간단히 ack -ch <pattern>.
  • @KyleStrand For me ack -ch < 패턴 > 발생 횟수가 아닌 발생 횟수가있는 줄만 계산
  • @MarcKees 맨 페이지를 보면 올바른 동작 인 것 같습니다. 지적 해 주셔서 감사합니다!

Answer

grep “s -o는 행을 무시하고 일치 항목 만 출력합니다. wc는 개수를 계산할 수 있습니다.

grep -o "needle" file | wc -l 

“바늘”또는 “다중 바늘”과도 일치합니다.

단어 한 단어 만 일치 시키려면 다음 명령 중 하나를 사용하십시오.

grep -ow "needle" file | wc -l grep -o "\bneedle\b" file | wc -l grep -o "\<needle\>" file | wc -l 

댓글

  • 여기에는 GNU grep (Linux, Cygwin, FreeBSD, OSX)가 필요합니다.
  • @wag \b\B 여기서합니까?
  • @Geek \ b는 단어 경계와 일치하고 \ B는 단어 경계와 일치하지 않습니다. 위의 대답은 양쪽 끝에서 \ b를 사용하면 더 정확할 것입니다.
  • 한 줄당 발생 횟수는 grep -n 옵션과 uniq -c … grep -no ' \ < needle \ > ' 파일 | uniq -c
  • @jameswarren uniq는 인접한 동일한 줄만 제거합니다. iv에 공급하기 전에 sort해야합니다. id = “604374c00f”>

중복 항목이 항상 바로 인접 해 있는지 확실하지 않은 경우

답변

GNU grep (항상 Linux 및 Cygwin, 때로는 다른 곳)이있는 경우 grep -o의 출력 행을 계산할 수 있습니다. div> : grep -o needle | wc -l.

Perl을 사용하면 다음과 같은 몇 가지 방법을 사용할 수 있습니다 ( 고정 ).

perl -lne "END {print $c} map ++$c, /needle/g" perl -lne "END {print $c} $c += s/needle//g" perl -lne "END {print $c} ++$c while /needle/g" 

POSIX 도구 만 사용하는 경우 가능한 한 한 가지 접근 방식은 grep에 전달하기 전에 일치하는 항목이있는 줄에 입력합니다. 예를 들어 “전체 단어를 찾는 경우 먼저 모든 비 단어 문자를 줄 바꿈으로 바꿉니다.

# equivalent to grep -ow "needle" | wc -l tr -c "[:alnum:]" "[\n*]" | grep -c "^needle$" 

그렇지 않으면 표준 명령이 없습니다. 특정 텍스트 처리이므로 sed ( “매조 키스트 인 경우)”또는 awk로 전환해야합니다.

awk "{while (match($0, /set/)) {++c; $0=substr($0, RSTART+RLENGTH)}} END {print c}" sed -n -e "s/set/\n&\n/g" -e "s/^/\n/" -e "s/$/\n/" \ -e "s/\n[^\n]*\n/\n/g" -e "s/^\n//" -e "s/\n$//" \ -e "/./p" | wc -l 

다음을 사용하는 더 간단한 솔루션은 sedgrep는 문자열 또는 일반 정규 표현식에서 작동하지만 고정 패턴 ( 예 : needleneedle에서 두 개의 ^needle 또는 \bneedle를 찾습니다.

sed "s/needle/\n&\n/g" | grep -cx "needle" 

위의 sed 대체에서 \n를 사용하여 줄 바꿈을 의미했습니다. 이것은 패턴 부분에서는 표준이지만 대체 텍스트에서는 이식성을 위해 \n를 백 슬래시-개행으로 대체합니다.

Answer

나처럼 실제로 “둘 다, 정확히 한 번”, (실제로는 “둘 다, 두 번”)을 원했다면 간단합니다. :

grep -E "thing1|thing2" -c 

출력 2을 확인합니다.

이 접근 방식의 이점 (정확히 한 번만 원하는 경우) 쉽게 확장 할 수 있습니다.

댓글

  • I ' ' 실제로 한 번만 표시되는지 ' 확실하지 않으세요? 모두 '이 단어 중 하나가 한 번 이상 존재하는 것을 찾고 있습니다.
  • 이것은 허용되는 대답이어야합니다. , grep에는 항목 수를 세는 옵션이 내장되어 있으며 이름도 분명합니다. “count”에 대한 -c로!

답변

또 awk 및 needle를 필드 구분자로 사용하는 솔루션 :

awk -F"^needle | needle | needle$" "{c+=NF-1}END{print c}" 

뒤에 구두점을 붙이고 그에 따라 필드 구분자를 변경합니다. 즉

awk -F"^needle[ ,.?]|[ ,.?]needle[ ,.?]|[ ,.?]needle$" "{c+=NF-1}END{print c}" 

또는 클래스 사용 : [^[:alnum:]]는 알파벳이 아닌 모든 문자를 포함합니다.

주석

  • 정규식 필드 구분 기호 (예 : GNU awk)를 지원하는 awk가 필요합니다.

답변

이것은 순수한 bash 솔루션입니다.

#!/bin/bash B=$(for i in $(cat /tmp/a | sort -u); do echo "$(grep $i /tmp/a | wc -l) $i" done) echo "$B" | sort --reverse 

Answer

이 예는 파일의 총계가 아니라 행당 발생 횟수 만 출력합니다. 이것이 원하는 경우 다음과 같이 작동 할 수 있습니다.

perl -nle "$c+=scalar(()=m/needle/g);END{print $c}" 

댓글

  • 맞습니다-제 예는 첫 번째 줄에서만 발생합니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다