“ Ungrep” - รูปแบบที่ไม่ตรงกัน


13

ฉันกำลังมองหาคำสั่งหรือสคริปต์ที่จะทำต่อไปนี้ - รับ:

file1.txt:

abcd
efgh 
ijkl
mnop

file2.txt:

123abcd123
123efgh123
123mnop123

ฉันต้องการคำสั่งที่ทำสิ่งนี้:

ungrep file1.txt file2.txt

และส่งคืนสิ่งต่อไปนี้:

ijkl

กล่าวอีกนัยหนึ่งคือให้บรรทัดใน file1.txt ซึ่งจะไม่ส่งคืนผลลัพธ์ใด ๆ ใน gre2 ของ file2.txt ฉันรู้ว่าฉันสามารถทำได้โดยทำซ้ำผ่าน file1.txt, grepping file2.txt สำหรับแต่ละบรรทัดและจัดเก็บผลลัพธ์และแสดงผลบรรทัดใด ๆ ที่ผลลัพธ์ว่างเปล่า แต่ฉันหวังว่าจะมีประสิทธิภาพมากขึ้นในการทำเช่นนี้

คำตอบ:


18

ด้วย GNU grepสิ่งต่อไปนี้น่าจะใช้ได้ ใช้-fตัวเลือกส่งผ่านfile1.txtเป็น "แฟ้มรูปแบบ" - แต่ส่งผ่านในครั้งที่สองเป็นไฟล์ข้อมูล ใช้-oเพื่อรายงานเฉพาะส่วนที่ตรงกัน สุดท้ายแยกคำเหล่านั้นที่จับคู่เพียงครั้งเดียว - เหล่านี้สอดคล้องกับบรรทัดจากfile1.txtที่ไม่พบการแข่งขันfile2.txtมา

grep -h -o -f  file1.txt file2.txt file1.txt | sort | uniq -u
ijkl

คำอธิบายที่ดีมาก ขอบคุณและ +1
unxnut

4
คุณสามารถใช้เอฟเฟกต์เดียวกันได้โดยไม่ต้องใช้ grep หากต้องการ: sort file1.txt <(grep -of file1.txt file2.txt) | uniq -uแต่เช่นเดียวกับโซลูชันของคุณจะใช้งานได้เมื่อไฟล์รูปแบบไม่มีตัวอักษรเมตาของ regex
rici

@rici นั่นเป็นจุดที่ดีมาก
iruvar

2
การปรับปรุง:grep -oFf file1.txt file2.txt | sort file1.txt - | uniq -u
Stéphane Chazelas

10

คุณสามารถทำได้awkเช่น:

awk '
  NR == FNR {w[$0]; next}
  {for (i in w) if (index($0,i)) delete w[i]}
  END {for (i in w) print i}' file1.txt file2.txt

โดยการใช้indexเรากำลังมองหาสตริงย่อยแทนที่จะจับคู่นิพจน์ทั่วไป

เนื่องจากเราลบคำออกจากอาร์เรย์ทันทีที่เราพบคู่ที่ตรงกันเราจึงหลีกเลี่ยงการค้นหาที่ไม่จำเป็น


1
ฉันจะยอมรับสิ่งนี้เท่านั้น มันไม่เรียกใช้การเรียงลำดับ O (n log n) ใด ๆ และไม่ล้มเหลวอย่างน่าประหลาดใจเมื่อรูปแบบมีเมตาอักขระ Regex และสามารถขยายเพื่อรองรับ regexes
Kaz

ฉันไม่อยากจะเชื่อเลยว่าการประเมินเพียงอย่างเดียวw[$0]นั้นมีผลข้างเคียงของการเพิ่มคีย์ในอาร์เรย์
Kaz

1
@Kaz ใช่ว่าอาจสร้างความสับสนและคุณพบว่าสคริปต์จำนวนมากไม่ได้รู้เท่าทันการจัดสรรองค์ประกอบของอาร์เรย์โดยไม่ได้ตั้งใจโดยทำif (a[$1])แทนif ($1 in a)ตัวอย่างเช่น เป็นกรณีของทุกคนawkรวมถึงต้นฉบับawkและnawkเมื่อดูมาตรฐานเมื่อวานนี้ฉันไม่สามารถระบุได้
Stéphane Chazelas

1
@Kaz ต่อไปนี้เป็นคำพูด POSIX: "แอปพลิเคชันจะต้องแน่ใจว่าดัชนีหลายมิติที่ใช้กับตัวดำเนินการinนั้นเป็นเครื่องหมายวงเล็บตัวดำเนินการinซึ่งทดสอบการมีอยู่ขององค์ประกอบอาร์เรย์นั้นจะไม่ทำให้องค์ประกอบนั้นมีอยู่จริง การอ้างอิงอื่น ๆ กับองค์ประกอบอาร์เรย์ที่ไม่มีอยู่จะสร้างขึ้นโดยอัตโนมัติ " มันสามารถพบได้โดยการเลื่อนหรือวรรคสองเพิ่มขึ้นจากที่นี่
jw013

1
ตราบใดที่file1ไม่ใหญ่ (สำหรับมูลค่าที่มาก) ฉันต้องการโซลูชันนี้เพราะไม่ต้องการการเรียงลำดับใด ๆfile2และคาดว่าจะมีประสิทธิภาพมากขึ้น
jw013
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.