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


8

이 입력에 대해 :

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"단어 ​​만 포함합니다. (대소 문자 구분 안함)


4
너무 광범위한 유권자에게 : 질문이 어떻게 더 구체적으로 표현 될 수 있습니까?
— Jacob Vlijm

@JacobVlijm "너무 많은 가능한 답변"이 있습니다. 선택 $RANDOM_LANGUAGE-누군가가 그 안에 해결책을 제시 할 수 있습니다.
— muru

@muru 반대로 하나의 언어로 제한하면 프로그래밍 (언어) 중심의 질문이 될 것입니다. 이제 문제 중심의 질문입니다. 가능한 많은 솔루션 (언어)이있을 수 있지만 명백한 솔루션은 많지 않습니다.
— Jacob Vlijm

답변:


13

에서 대소 문자를 구분하지 않고 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'

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


왜 교체해야합니까? 교체하지 않고 직접 계산할 수 없습니까?
— αғsнιη

실제로 우리가 셀 수있는 코드는 약간 더 깁니다 : stackoverflow.com/questions/9538542/…
— muru

gawk 명령에 대한 투표.
— Sri

9

소스 파일이 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으로 바꾸십시오.


N> 4의 경우 실패합니다. 첫 번째 grep는로 끝나야 *합니다.
— ps95

1
나는 당신이 이것을 N = 50에 쓸 수 없다는 것을 의미합니다. 그리고 질문은 정확히 3에 대한 것이므로 2보다 작거나 같은 모든 출력을 버리는 또 다른 grep이 필요합니다 this. grep -iv '.*this.*this.*this.*this.*' tmp.txt | grep -i '.*this.*this.*this.* |grep -iv '.*this.*this.'
— ps95

@ prakharsingh95 n> 4에서 실패하지 않았으며 첫 번째 grep에는 *가 필요하지 않습니다.
— Sri

1
@KasiyA 내 대답은 무엇입니까?
— Sri

5
약간 단순화하십시오 : grep -Eiv '(.*this){4,}' | grep -Ei '(.*this){3}'-N = 50에 실용적이 될 수 있습니다.
— muru

9

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

#!/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())

나는 파이썬 전문가가 아닙니다. 파일에서 어떻게 읽을 수 있습니까? 감사
— αғsнιη

1
@KasiyA 파일을 인수로 사용하도록 편집했습니다.
— Jacob Vlijm

궁금한 점 : 왜 두 번째 코드 스 니펫에서 생성기를 사용하지 않았습니까?
— muru

6

당신은 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


이미 게시 했지만 좋은 설명입니다.
— muru

@muru 오, 나는 그것을 보지 못했다! 내 사과와 당신을 위해 +1.
— fedorqui

5

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

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

1
감사합니다 . 대신 sed ...명령을 제거 하고 -o옵션을 추가 할 수 있습니다 grep -oi ....
— αғsнιη

더 간단하게 :$(grep -ic "this" <<<"$line")
— muru

2
@muru 아니요, -c옵션은 각 줄의 "this"단어가 아니라 "this"와 일치하는 줄 수를 계산 합니다.
— αғsнιη

1
@KasiyA 아, 그렇습니다. 내 잘못이야.
— muru

@KasiyA는 않을 것이다 -l그리고 -w이 경우에 해당 될?
— ps95

4

Vim에 있다면 :

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

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


Vim을 사용할 때 단어가 n 인 행을 검색하는 좋은 예입니다.
— Sri

0

루비 원 라이너 솔루션 :

$ 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우리에게 문자열의 발생 수를 제공합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.