일반적으로 grep
패턴과 일치하는 모든 행이 출력됩니다. 패턴과 여러 번 일치하는 행을 찾고 싶습니다. 예를 들어, 내 검색 패턴이 "foo"인 경우:
foo bar # Would not be matched
foo foo bar # Would be matched
bar foofoo # Would be matched
foobarfoo # Would be matched
grep
검색 패턴과 일치하는 항목이 여러 개 포함된 행만 찾도록 할 수 있는 방법이 있습니까 ?
답변1
grep -E "(foo.*){2}" file
이는 파일 또는 출력의 각 줄에서 최소 2번 일치하며, 제공할 수 있는 최소 일치 수입니다.
답변2
일치하는 모든 줄을 일치시키려면어느문자열을 두 번:
grep '\(.\{1,\}\).*\1'
다음을 변경하여 일치하는 길이를 변경할 수 있습니다 1,
.
seq 10000 | grep '\(.\{2,\}\).*\1'
이는 기본 정규 표현식(갈아 바수다)이므로 POSIX 호환 grep
.
탐욕스럽지 않은 정규식(모든 곳에서 지원되지 않음)을 사용하도록 정규식을 변환하면 일치 속도가 빨라지지 않는 것 같습니다.
grep -E '(..*?).*?\1'
그래프는 각 n개 숫자의 100개 행(~행 길이)에서 비 욕심쟁이 실행 유무에 따른 실행 시간(초)을 보여줍니다.
greedy() {
a=`seq $1`;
yes $a | head -n 100 | grep '\(.\{1,\}\).*\1' | LC_ALL=C wc;
}
nongreedy() {
a=`seq $1`;
yes $a | head -n 100 | grep -E '(..*?).*?\1' | LC_ALL=C wc;
}
export -f greedy
export -f nongreedy
parallel --jl my.log {2} {1}000 {2} ::: {1..100} ::: greedy nongreedy
답변3
grep "foo.*foo" file.txt
foo
그러면 두 번 이상 발생한 행만 반환됩니다 . 한 번만 나타나는 행은 반환되지 않습니다.
위 코드는 대부분의 경우 따옴표 없이 작동하지만 디렉토리의 glob과 일치하는 파일 이름이 있는 다른 경우(예: )에는 foo.barfoo
정규식을 인용해야 하므로 큰따옴표를 포함하도록 답변을 편집했습니다.