ฉันจะได้รับบรรทัดที่คำใดคำหนึ่งซ้ำซ้ำกันทุกครั้งได้อย่างไร


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

การรับทั้งบรรทัดมีเพียงสามคำที่ซ้ำกัน (ตรงกับกรณีตาย)


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 ทางซ้ายส่งเอาต์พุตทุกบรรทัดที่ไม่มีการเกิดตัวพิมพ์เล็กและตัวพิมพ์เล็กของ "this" ใน tmp.txt

ผลลัพธ์ถูกส่งไปยัง grep ด้านขวาซึ่งส่งเอาต์พุตบรรทัดทั้งหมดที่มี 3 ครั้งขึ้นไปในผลลัพธ์ grep ด้านซ้าย

อัปเดต: ขอบคุณ @Muru นี่เป็นรุ่นที่ดีกว่าของโซลูชันนี้

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

แทนที่ 4 ด้วย n + 1 และ 3 ด้วย n


นี้จะล้มเหลว N> 4 และคนแรกที่ตอบสนองความต้องการที่จะสิ้นสุดในgrep *
ps95

1
ฉันหมายความว่าคุณไม่สามารถเขียนนี้ N = 50 และคำถามคือสำหรับตรงสามดังนั้นคุณต้อง 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

ใน 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())

ฉันไม่ใช่ผู้เชี่ยวชาญของหลามฉันจะอ่านจากไฟล์ได้อย่างไร ขอบคุณ
αғ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ตัวเอง ด้วยวิธีนี้บรรทัดจะมีฟิลด์มากถึง +1 เท่าที่คำthisปรากฏ

  • 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 Ah ใช่ ความผิดฉันเอง.
muru

@KasiyA จะไม่-lและ-wจะเทียบเท่าในกรณีนี้หรือไม่?
ps95

4

หากคุณอยู่ในกลุ่ม:

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

นี่จะพิมพ์บรรทัดที่ตรงกัน


ตัวอย่างที่ดีในการค้นหาบรรทัดที่มีการเกิด n คำเมื่อใช้เป็นกลุ่ม
ศรี

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

ทำงานในแบบที่ค่อนข้างง่าย: เราเปลี่ยนเส้นทางไฟล์เป็น stdin ของ ruby, ruby ​​รับสายจาก stdin, ทำความสะอาดมันด้วยchompและdowncase, และscan().countทำให้เรามีจำนวน substring เกิดขึ้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.