Как я могу получить строки, где определенное слово повторяется точно N времена?

Для этого данного входа:

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

Получение целых строк содержит, только три повторили "это" слова. (нечувствительное к регистру соответствие)

8
задан 4 January 2015 в 19:34

7 ответов

В 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'

количество полей будет еще одним, чем количество разделителей.

13
ответ дан 23 November 2019 в 05:21

Принятием Вашего исходного файла является tmp.txt,

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

левые grep выводы все строки, которые не имеют 4 или больше нечувствительных к регистру случаев "этого" в tmp.txt.

результат передается по каналу направо grep, какие выводы все строки с 3 или больше случаями в левом grep заканчиваются.

Обновление: Благодаря @Muru вот лучшая версия этого решения,

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

замена 4 с n+1 и 3 с n.

9
ответ дан 23 November 2019 в 05:21

Если Вы находитесь в Vim:

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

Это просто распечатает подобранные строки.

4
ответ дан 23 November 2019 в 05:21

Принятие строк хранится в файле, названном FILE:

while read line; do 
    if [ $(grep -oi "this" <<< "$line" | wc -w)  = 3 ]; then 
        echo "$line"; 
    fi  
done  <FILE
5
ответ дан 23 November 2019 в 05:21

В Python это сделало бы задание:

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

Конечно, слово, "это" может быть заменено любым другим словом (или другая строка или раздел строки), и количество случаев на строку, может быть установлено на любое другое значение в строке:

    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())
9
ответ дан 23 November 2019 в 05:21

Можно играть немного с 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 самостоятельно. Таким образом, строка будет иметь столько же полей +1 сколько времена слово this появляется.

  • Для создания этого нечувствительным к регистру мы используем IGNORECASE = 1. Посмотрите ссылку: Чувствительность к регистру в Соответствии.

  • Затем это - просто вопрос высказывания NF==4 получить все те строки наличие this точно три раза. Больше кода не необходимо с тех пор {print $0} (то есть, распечатайте текущую строку), поведение по умолчанию awk когда выражение оценивает к True.

6
ответ дан 23 November 2019 в 05:21

Решение остроты Ruby:

$ 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

Работы довольно простым способом: мы перенаправляем файл в stdin рубина, рубин получает строку от stdin, очищает его с chomp и downcase, и scan().count дает нам количество случаев подстроки.

0
ответ дан 23 November 2019 в 05:21

Другие вопросы по тегам:

Похожие вопросы: