grep -c
를 사용하여 총 발생 횟수를 계산하면 파일에서 문자열이 몇 번 발생하는지 찾는 데 유용합니다. 하지만 한 줄에 한 번만 각 항목을 계산합니다. 한 줄에 여러 번 발생하는 횟수를 계산하는 방법은 무엇입니까?
다음보다 더 우아한 것을 찾고 있습니다.
perl -e "$_ = <>; print scalar ( () = m/needle/g ), "\n""
댓글
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
다음을 사용하는 더 간단한 솔루션은 sed
및 grep
는 문자열 또는 일반 정규 표현식에서 작동하지만 고정 패턴 ( 예 : 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}"
댓글
- 맞습니다-제 예는 첫 번째 줄에서만 발생합니다.
grep
가 지정되어 있음을 알고 있지만ack
를 사용하는 모든 사용자의 경우 대답은 간단히ack -ch <pattern>
.