특정 단어가 정확히 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.