grep -c
파일에서 특정 문자열이 나타나는 횟수를 찾는 데 유용하지만 각 발생은 한 줄에 한 번만 계산됩니다. 각 줄에서 여러 번 발생하는 횟수를 계산하는 방법은 무엇입니까?
나는 다음보다 더 우아한 것을 찾고 있습니다.
perl -e '$_ = <>; print scalar ( () = m/needle/g ), "\n"'
답변1
grep은 -o
일치하는 항목만 출력하고 행을 무시합니다 wc
.
grep -o 'needle' file | wc -l
이는 "needles" 또는 "multineedle"과도 일치합니다.
단일 단어만 일치시키려면 다음 명령 중 하나를 사용하십시오.
grep -ow 'needle' file | wc -l
grep -o '\bneedle\b' file | wc -l
grep -o '\<needle\>' file | wc -l
답변2
GNU grep(항상 Linux 및 Cygwin에서, 때로는 다른 곳에서)이 있는 경우 다음을 수행할 수 있습니다.출력 라인 수 계산grep -o
: 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
and 를 사용하는 더 간단한 솔루션 입니다(예: 또는 에서 두 번 발생하는 것을 찾습니다).grep
^needle
\bneedle
needleneedle
sed 's/needle/\n&\n/g' | grep -cx 'needle'
위의 sed 대체에서는 \n
개행 문자를 참조하고 있습니다. 이는 패턴 부분에서는 표준이지만 대체 텍스트에서는 이식성을 위해 백슬래시 개행 문자로 대체합니다 \n
.
답변3
나처럼 실제로 "둘 다; 각각 정확히 한 번" (실제로는 "둘 중 하나; 두 번")을 원한다면 간단합니다.
grep -E "thing1|thing2" -c
출력을 확인하십시오 2
.
이 접근 방식의 이점(정확히 한 번인 경우)예당신이 원하는 것은 쉽게 확장 가능하다는 것입니다.
답변4
이 작업을 수행해야 하지만 여러 검색어에 대해 수행해야 합니다. 열에 나열하고 각 열의 발생 횟수를 나열하고 싶습니다.
내 bash 전용 한 줄 솔루션은 다음과 같습니다.
grep -o -E 'borp|flarb' flarb.log | sort | uniq -c
910 borp
9090 flarb