เครื่องมือในยูนิกซ์เพื่อลบไฟล์ข้อความ?


16

ฉันมีไฟล์ขนาดใหญ่ประกอบด้วยเขตข้อมูลข้อความคั่นด้วยเครื่องหมายอัฒภาคในรูปแบบของตารางขนาดใหญ่ มันได้รับการจัดเรียง ฉันมีไฟล์ขนาดเล็กที่ประกอบด้วยฟิลด์ข้อความเดียวกัน เมื่อถึงจุดหนึ่งบางคนต่อไฟล์นี้กับผู้อื่นแล้วเรียงลำดับเพื่อจัดทำไฟล์ขนาดใหญ่ที่อธิบายไว้ข้างต้น ฉันต้องการลบเส้นของไฟล์ขนาดเล็กออกจากไฟล์ใหญ่ (เช่นสำหรับแต่ละบรรทัดในไฟล์ขนาดเล็กหากมีสตริงการจับคู่อยู่ในไฟล์ขนาดใหญ่ให้ลบบรรทัดนั้นในไฟล์ขนาดใหญ่)

ไฟล์มีลักษณะเช่นนี้โดยประมาณ

GenericClass1; 1; 2; NA; 3; 4;
GenericClass1; 5; 6; NA; 7; 8;
GenericClass2; 1; 5; NA; 3; 8;
GenericClass2; 2; 6; NA; 4; 1;

ฯลฯ

มีวิธีที่ดีงามอย่างรวดเร็วในการทำเช่นนี้หรือฉันต้องใช้ awk?

คำตอบ:


28

grepคุณสามารถใช้ ให้ไฟล์ขนาดเล็กเป็นอินพุตและบอกให้ค้นหาบรรทัดที่ไม่ตรงกัน:

grep -vxFf file.txt bigfile.txt > newbigfile.txt

ตัวเลือกที่ใช้คือ:

   -F, --fixed-strings
          Interpret PATTERN as a  list  of  fixed  strings,  separated  by
          newlines,  any  of  which is to be matched.  (-F is specified by
          POSIX.)
   -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)

   -v, --invert-match
          Invert the sense of matching, to select non-matching lines.  (-v
          is specified by POSIX.)
   -x, --line-regexp
          Select only those matches that exactly match the whole line.  
          (-x is specified by POSIX.)

นีซทำงานได้อย่างสมบูรณ์แบบ ขอบคุณมาก ๆ.
Escher

1
มันเจ๋งที่มันใช้งานได้ แต่สำหรับฉันแล้วมันน่าจะดีกว่าถ้ามี-xตัวเลือกเช่นกันในกรณีที่มีไฟล์ย่อยในไฟล์เล็ก ๆ เกิดขึ้นกับฉันจะมีซับสตริงของอีกไฟล์หนึ่งในไฟล์หลัก นอกจากนี้อาจเป็นไปได้ว่าคำตอบของ @ UlrichSchwarz นั้นเร็วกว่า
rici

18

comm เป็นเพื่อนของคุณ:

NAME comm - เปรียบเทียบไฟล์ที่เรียงลำดับสองไฟล์ต่อบรรทัด

สรุปคำศัพท์ [ตัวเลือก] ... FILE1 FILE2

DESCRIPTION เปรียบเทียบไฟล์ที่เรียงลำดับ FILE1 และ FILE2 ทีละบรรทัด

   With  no  options, produce three-column output.  Column one contains lines unique to FILE1, column two contains
   lines unique to FILE2, and column three contains lines common to both files.

   -1     suppress column 1 (lines unique to FILE1)

   -2     suppress column 2 (lines unique to FILE2)

   -3     suppress column 3 (lines that appear in both files)

( commอาจมีผลประโยชน์ด้านประสิทธิภาพมากกว่าgrepเนื่องจากคำนึงถึงการจัดเรียง)

ตัวอย่างเช่น:

comm -1 -3 file.txt bigfile.txt > newbigfile.txt

2
ข้อดีของการใช้คำสั่ง grep สำหรับรายการที่เรียงลำดับ นี่จะเป็นคำตอบที่ดีกว่าถ้าคุณให้ตัวอย่างบรรทัดคำสั่งที่เจาะจงเช่นcomm -1 -3 file.txt bigfile.txt > newbigfile.txt
Steve Midgley

ฉันยืนยันว่าฉันลองใช้คำสั่ง grep รายงานข้างต้นด้วยไฟล์ประมาณ 100MB และฉันพบข้อผิดพลาด "ถูกฆ่า" ลองใช้คอมมันสำเร็จแล้ว
Gianluca Casati

การเปลี่ยนเส้นทางคำสั่งมีประโยชน์สำหรับไฟล์ที่ไม่ได้เรียงลำดับหรือหากคุณต้องการมากกว่าสองไฟล์:comm -1 -3 <(sort BAD.txt GOOD.txt) <(sort FILES.txt)
odinho - Velmont
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.