aa
매우 큰 파일에서 반복되는 패턴의 수를 세고 싶습니다 . 그래서 다음 명령을 사용합니다.
grep -o "aa" ./bwt/dblp.txt | wc -l
예를 들어 문자열이 없으면 작동하며 aaa
1개의 패턴에만 일치합니다. 내 사용 사례에서는 a
패턴을 나타내기 위해 처음 2s가 필요 하지만 a
두 번째 패턴이 되려면 마지막 2s가 필요합니다(가운데 a
패턴을 aaa
재사용할 수 있음을 의미).
이 목표를 어떻게 달성할 수 있나요?
파일이 상당히 크기 때문에 가능하다면 "최적화된" 방식이 더 좋습니다. 그럼에도 불구하고 실행 가능한 모든 솔루션은 분명히 환영합니다.
답변1
이를 위해서는 Perl 정규 표현식이 필요합니다. grep
이 플래그를 지원하는 a를 사용하십시오 -P
.
grep -oP '(?<=a)a' file | wc -l
이것은 긍정적이다뒤를 봐. 이는 a
다른 하나 앞에 오는 싱글과 일치합니다 a
.
원하는 경우 perl
(또는 플래그 grep
를 지원하지 않는 경우 -P
):
perl -ne 'while(m/(?<=a)a/g){$a++}END{print "$a\n"}' file
예:
$ cat file
aa
aaa
aaaa
첫 번째 행은 1개 일치 항목이어야 하고, 두 번째 행은 2개 항목이어야 하며, 세 번째 행은 총 6개 항목이어야 합니다.
$ grep -oP '(?<=a)a' file | wc -l
6
답변2
다음과 같이 aa
데이터 파일의 예 와 같이 반복되는 문자 쌍의 수를 계산할 수 있습니다 .big_file
tr -cs a '\012' <big_file | awk '/aa/{n += length - 1}; END {print n+0}'
선은 다음과 같이 해석될 수 있습니다.
tr
개행 문자가 아닌 문자 시퀀스를 변경합니다a
. 이렇게 하면 여러 항목이aa...
별도 의 줄로 구분됩니다 .awk
0이 아닌 선의 길이를 계산합니다 . N 문자 시퀀스에 N-1 개의 중첩 쌍이 포함되어 있다는 사실을 활용하여 중첩 쌍 수를 추가하고 파일 끝에 합계를 생성할 수 있습니다.
실제로 파일이 "매우 크기" 때문에 grep
다음과 같이 파이프에 a를 포함하면 더 나은 응답을 얻을 수 있습니다.
tr -cs a '\012' <big_file | grep aa | awk '{n += length - 1}; END {print n+0}'
답변3
어떤 이유로 혼돈의 대답은 내 시스템(Debian 11.5, GNU grep 3.6)에 아무것도 출력하지 않습니다. 다른 사람에게도 효과가 있을 경우를 대비해 나에게 효과가 있었던 방법은 다음과 같습니다.
pcregrep -o1 -o2 '(\w)(?=(\w))' file
이는 제안된 것과 정신이 비슷합니다. 캡처 그룹 2에서 첫 번째 문자 뒤에 다른 문자가 오면 캡처 그룹 1을 사용하여 첫 번째 문자를 일치시키고, 미래 예측을 사용하여 후자만 일치하므로 여전히 Can을 사용할 수 있습니다. 그걸 써. 그런 다음 두 그룹을 모두 사용 -o1
하고 표시합니다 -o2
.
이는 길이의 하위 시퀀스로 직접 일반화될 수 있습니다 n
.
pcregrep -o1 -o2 '(\w)(?=(\w{n-1}))' file
답변4
grep -ow aa ./bwt/dblp.txt | wc -l