겹치는 패턴에 대한 Grep

겹치는 패턴에 대한 Grep

aa매우 큰 파일에서 반복되는 패턴의 수를 세고 싶습니다 . 그래서 다음 명령을 사용합니다.

grep -o "aa" ./bwt/dblp.txt | wc -l

예를 들어 문자열이 없으면 작동하며 aaa1개의 패턴에만 일치합니다. 내 사용 사례에서는 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...별도 의 줄로 구분됩니다 .
  • awk0이 아닌 선의 길이를 계산합니다 . 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

관련 정보