Làm cách nào tôi có thể nhận được các dòng trong đó một từ cụ thể được lặp lại chính xác N lần?


8

Đối với đầu vào này:

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

Tôi muốn đầu ra này:

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

Bắt toàn bộ dòng chỉ chứa ba từ "này" lặp đi lặp lại. (trường hợp không khớp)


4
Đối với cử tri quá rộng: làm thế nào một câu hỏi có thể trở nên cụ thể hơn?
Jacob Vlijm

@JacobVlijm Trong đó có "quá nhiều câu trả lời có thể". Chọn $RANDOM_LANGUAGE- ai đó sẽ có thể đưa ra một giải pháp trong đó.
muru

@muru Tôi sẽ nói ngược lại, giới hạn nó trong một ngôn ngữ sẽ làm cho nó trở thành một câu hỏi tập trung vào lập trình (ngôn ngữ). Bây giờ nó là một vấn đề trung tâm vấn đề . Có thể có nhiều giải pháp khả thi (ngôn ngữ), nhưng không có nhiều giải pháp rõ ràng.
Jacob Vlijm

Câu trả lời:


13

Trong perl, thay thế thisbằng chính trường hợp không nhạy cảm và đếm số lần thay thế:

$ 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

Thay vào đó, sử dụng số lượng trận đấu :

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

Nếu bạn có GNU awk, một cách rất đơn giản:

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

Số lượng các trường sẽ nhiều hơn một số lượng phân cách.


Tại sao phải thay thế? chúng ta không thể đếm nó trực tiếp mà không thay thế?
lúc 18 giờ 33 phút

Thật vậy, chúng ta có thể đếm, mã dài hơn một chút: stackoverflow.com/questions/9538542/
Khăn

Upvote cho lệnh gawk.
Sri

9

Giả sử tệp nguồn của bạn là tmp.txt,

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

Grep bên trái xuất ra tất cả các dòng không có 4 hoặc nhiều lần xuất hiện không phân biệt chữ hoa chữ thường của "this" trong tmp.txt.

Kết quả được dẫn đến grep bên phải, kết quả này xuất ra tất cả các dòng có 3 lần xuất hiện trở lên trong kết quả grep bên trái.

Cập nhật: Cảm ơn @Muru, đây là phiên bản tốt hơn của giải pháp này,

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

thay 4 bằng n + 1 và 3 bằng n.


Điều này sẽ thất bại cho N> 4. Và grepnhu cầu đầu tiên kết thúc *.
ps95

1
Ý tôi là bạn không thể viết cái này cho N = 50. Và câu hỏi dành cho chính xác ba vì vậy bạn cần một grep khác loại bỏ tất cả các đầu ra có chứa ít hơn hoặc bằng hai this. grep -iv '.*this.*this.*this.*this.*' tmp.txt | grep -i '.*this.*this.*this.* |grep -iv '.*this.*this.'
ps95

@ prakharsingh95 Không thành công cho n> 4 và * không bắt buộc trong grep đầu tiên.
Sri

1
@KasiyA bạn lấy gì cho câu trả lời của tôi?
Sri

5
Đơn giản hóa nó một chút: grep -Eiv '(.*this){4,}' | grep -Ei '(.*this){3}'- điều này có thể làm cho nó thực tế cho N = 50.
muru

9

Trong python, điều này sẽ làm công việc:

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

đầu ra:

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

Hoặc để đọc từ một tệp, với tệp là đối số:

#!/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)
  • Dán tập lệnh vào một tập tin trống, lưu nó dưới dạng find_3.py, chạy nó bằng lệnh:

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

Tất nhiên, từ "này" có thể được thay thế bằng bất kỳ từ nào khác (hoặc phần chuỗi hoặc dòng khác) và số lần xuất hiện trên mỗi dòng có thể được đặt thành bất kỳ giá trị nào khác trong dòng:

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

Biên tập

Nếu tệp sẽ lớn (hàng trăm nghìn / triệu dòng), mã bên dưới sẽ nhanh hơn; nó đọc tệp trên mỗi dòng thay vì tải tệp cùng một lúc:

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

Tôi không phải là chuyên gia python, làm thế nào tôi có thể đọc từ tập tin? thanks
αғsнιη

1
@KasiyA chỉnh sửa để sử dụng tệp làm đối số.
Jacob Vlijm

Chỉ tò mò: Tại sao bạn không sử dụng trình tạo trong đoạn mã thứ hai?
muru

6

Bạn có thể chơi một chút với awkđiều này:

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

Điều này trả về:

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

Giải trình

  • Những gì chúng ta làm là xác định dấu tách trường cho thischính nó. Theo cách này, dòng sẽ có nhiều trường +1 lần số từ thisxuất hiện.

  • Để làm cho nó không nhạy cảm, chúng tôi sử dụng IGNORECASE = 1. Xem tài liệu tham khảo: Độ nhạy trường hợp trong Kết hợp .

  • Sau đó, nó chỉ là một vấn đề NF==4để nói để có được tất cả các dòng có thischính xác ba lần. Không cần thêm mã, vì {print $0}(nghĩa là in dòng hiện tại) là hành vi mặc định awkkhi biểu thức ước tính True.


Đã được đăng , nhưng giải thích tốt.
muru

@muru oh, tôi đã không nhìn thấy nó! Tôi xin lỗi và +1 cho bạn.
fedorqui

5

Giả sử các dòng được lưu trữ trong một tệp có tên FILE:

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

1
Cảm ơn bạn, bạn có thể loại bỏ sed ...lệnh của bạn và thêm -otùy chọn grep -oi ...thay thế.
αғsнιη

Đơn giản hơn:$(grep -ic "this" <<<"$line")
muru

2
@muru Không, -ctùy chọn sẽ đếm số dòng khớp với từ "này" chứ không phải số từ "này" trong mỗi dòng.
αғsнιη

1
@KasiyA À, vâng. Lỗi của tôi.
muru

@KasiyA, sẽ không -l-wtương đương trong trường hợp này?
ps95

4

Nếu bạn đang ở Vim:

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

Điều này sẽ chỉ in các dòng phù hợp.


Ví dụ hay để tìm kiếm các dòng có n lần xuất hiện của từ, khi sử dụng Vim.
Sri

0

Giải pháp Ruby one-liner:

$ 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

Hoạt động theo một cách khá đơn giản: chúng tôi chuyển hướng tập tin vào stdin của ruby, ruby ​​lấy dòng từ stdin, làm sạch nó chompdowncasescan().countcho chúng tôi số lần xuất hiện của một chuỗi con.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.