특정 단어가 정확히 N 번 반복되는 줄을 얻으려면 어떻게해야합니까? is THIS

이 입력에 대해 :

How to get This line that this word repeated 3 times in THIS line?
But not this line which is THIS word repeated 2 times.
And I will get This line with this here and This one
A test line with four this and This another THIS and last this

이 출력을 원합니다.

How to get This line that this word repeated 3 times in THIS line?
And I will get This line with this here and This one

전체 줄을 얻는 것은 세 개의 반복 된 “this”단어 ​​만 포함합니다. (대소 문자 구분 안함)



답변

에서 대소 문자를 구분하지 않고 perl교체 this하고 교체 횟수를 계산합니다.

$ perl -ne 's/(this)/$1/ig == 3 && print' <<EOF
How to get This line that this word repeated 3 times in THIS line?
But not this line which is THIS word repeated 2 times.
And I will get This line with this here and This one
A test line with four this and This another THIS and last this
EOF
How to get This line that this word repeated 3 times in THIS line?
And I will get This line with this here and This one

사용하여 일치하는 수를 대신 :

perl -ne 'my $c = () = /this/ig; $c == 3 && print'

GNU awk가 있다면 매우 간단한 방법입니다.

gawk -F'this' -v IGNORECASE=1 'NF == 4'

필드 수는 구분 기호 수보다 하나 더 많습니다.


답변

소스 파일이 tmp.txt라고 가정하면,

grep -iv '.*this.*this.*this.*this' tmp.txt | grep -i '.*this.*this.*this.*'

왼쪽 grep은 tmp.txt에서 대소 문자를 구분하지 않는 “this”가 4 번 이상없는 모든 행을 출력합니다.

결과는 오른쪽 그렙으로 파이프되어 왼쪽 그렙 결과에서 3 번 이상 나타나는 모든 줄을 출력합니다.

업데이트 : @Muru 덕분 에이 솔루션의 더 나은 버전이 있습니다.

grep -Eiv '(.*this){4,}' tmp.txt | grep -Ei '(.*this){3}'

4를 n + 1로 바꾸고 3을 n으로 바꾸십시오.


답변

파이썬에서는이 작업을 수행합니다.

#!/usr/bin/env python3

s = """How to get This line that this word repeated 3 times in THIS line?
But not this line which is THIS word repeated 2 times.
And I will get This line with this here and This one
A test line with four this and This another THIS and last this"""

for line in s.splitlines():
    if line.lower().count("this") == 3:
        print(line)

출력 :

How to get This line that this word repeated 3 times in THIS line?
And I will get This line with this here and This one

또는 파일을 인수로하여 파일에서 읽습니다.

#!/usr/bin/env python3
import sys

file = sys.argv[1]

with open(file) as src:
    lines = [line.strip() for line in src.readlines()]

for line in lines:
    if line.lower().count("this") == 3:
        print(line)
  • 스크립트를 빈 파일에 붙여넣고로 저장 find_3.py한 후 다음 명령으로 실행하십시오.

    python3 /path/to/find_3.py <file_withlines>
    

물론 “this”라는 단어를 다른 단어 (또는 다른 문자열 또는 줄 섹션)로 바꿀 수 있으며 줄당 발생 횟수를 줄의 다른 값으로 설정할 수 있습니다.

    if line.lower().count("this") == 3:

편집하다

파일이 크면 (수만 / 백만 줄) 아래 코드가 더 빠릅니다. 파일을 한 번에로드하는 대신 한 줄에 파일을 읽습니다.

#!/usr/bin/env python3
import sys
file = sys.argv[1]

with open(file) as src:
    for line in src:
        if line.lower().count("this") == 3:
            print(line.strip())


답변

당신은 awk이것을 위해 조금 놀 수 있습니다 :

awk -F"this" 'BEGIN{IGNORECASE=1} NF==4' file

이것은 다음을 반환합니다.

How to get This line that this word repeated 3 times in THIS line?
And I will get This line with this here and This one

설명

  • 우리가하는 일은 필드 구분 기호를 this자체적 으로 정의하는 것입니다. 이런 식으로, 라인은 단어 this가 나타나는 횟수만큼의 필드 +1을 갖습니다 .

  • 대소 문자를 구분하지 않으려면을 사용 IGNORECASE = 1합니다. 참조 : 대소 문자 구분의 대소 문자 구분을 참조하십시오 .

  • 그런 다음 NF==4모든 라인을 this정확히 세 번 가져야 한다는 것은 단지 문제입니다 . 표현식이로 평가 될 때 {print $0}의 기본 동작 이므로 더 이상 코드가 필요하지 않습니다 (즉, 현재 행을 인쇄) .awkTrue


답변

행이 다음과 같은 파일에 저장되어 있다고 가정합니다 FILE.

while read line; do
    if [ $(grep -oi "this" <<< "$line" | wc -w)  = 3 ]; then
        echo "$line";
    fi
done  <FILE


답변

Vim에 있다면 :

g/./if len(split(getline('.'), 'this\c', 1)) == 4 | print | endif

일치하는 줄만 인쇄합니다.


답변

루비 원 라이너 솔루션 :

$ ruby -ne 'print $_ if $_.chomp.downcase.scan(/this/).count == 3' < input.txt
How to get This line that this word repeated 3 times in THIS line?
And I will get This line with this here and This one

아주 간단한 방식으로 작품 : 우리가 루비의 표준 입력으로 파일을 재 지정은, 루비, 표준 입력에서 라인을 가져 그것을 정리 chomp하고 downcase, 그리고 scan().count우리에게 문자열의 발생 수를 제공합니다.