มีเครื่องมือใดบ้างที่สามารถรับบรรทัดที่ไฟล์ A มี แต่ไฟล์ B ไม่มี? ฉันสามารถสร้างสคริปต์ง่าย ๆ ด้วยเช่น perl แต่ถ้ามีอะไรทำนองนี้มีอยู่แล้วฉันจะประหยัดเวลานับจากนี้
มีเครื่องมือใดบ้างที่สามารถรับบรรทัดที่ไฟล์ A มี แต่ไฟล์ B ไม่มี? ฉันสามารถสร้างสคริปต์ง่าย ๆ ด้วยเช่น perl แต่ถ้ามีอะไรทำนองนี้มีอยู่แล้วฉันจะประหยัดเวลานับจากนี้
คำตอบ:
ใช่. grep
เครื่องมือมาตรฐานสำหรับการค้นหาไฟล์สำหรับสตริงข้อความสามารถใช้เพื่อลบบรรทัดทั้งหมดในไฟล์เดียวจากอีกไฟล์หนึ่ง
grep -F -x -v -f fileB fileA
สิ่งนี้ทำงานโดยใช้แต่ละบรรทัดใน fileB เป็นรูปแบบ ( -f fileB
) และถือว่าเป็นสตริงธรรมดาที่จะจับคู่ (ไม่ใช่ regex ปกติ) ( -F
) คุณบังคับให้การแข่งขันเกิดขึ้นกับทั้งบรรทัด ( -x
) และพิมพ์เฉพาะบรรทัดที่ไม่ตรงกัน ( -v
) ดังนั้นคุณจึงพิมพ์บรรทัดใน fileA ที่ไม่มีข้อมูลเหมือนกับบรรทัดใด ๆ ใน fileB
ข้อเสียของโซลูชันนี้คือการไม่คำนึงถึงลำดับการสั่งซื้อและหากข้อมูลของคุณมีบรรทัดที่ซ้ำกันในที่ต่าง ๆ คุณอาจไม่ได้สิ่งที่คุณคาดหวัง diff
วิธีการแก้ปัญหาว่าคือการใช้เครื่องมือการเปรียบเทียบจริงเช่น คุณสามารถทำได้โดยการสร้างไฟล์ diff ที่มีค่าบริบทที่ 100% ของบรรทัดในไฟล์จากนั้นแยกมันสำหรับเพียงบรรทัดที่จะถูกลบออกหากแปลงไฟล์ A เป็นไฟล์ B (หมายเหตุคำสั่งนี้ยังลบ diff การจัดรูปแบบหลังจากที่ได้รับบรรทัดที่ถูกต้อง)
diff -U $(wc -l < fileA) fileA fileB | sed -n 's/^-//p' > fileC
-u
อาร์กิวเมนต์ตัวพิมพ์เล็กจะใช้พารามิเตอร์ของตัวเลขตราบใดที่ไม่เว้นวรรคตามด้วยช่องว่าง ข้อดีของวิธีที่ฉันมีมาก่อนคือมันจะทำงานโดยมีหรือไม่มีค่าดังนั้นคุณสามารถใช้บางอย่างในรูทีนคำสั่งย่อยนั้นที่ส่งคืนไม่ใช่เอาต์พุต ตัวพิมพ์ใหญ่ '-U' ในทางกลับกันจำเป็นต้องมีอาร์กิวเมนต์
diff
ท่อทำงานขอบคุณรักษา
grep
จำเป็น ตัวอย่าง:grep -F -x -v -f <(sort fileB) <(sort fileA)
diff
คือตำแหน่งนั้นในไฟล์จะถูกนำมาพิจารณา
คำตอบนั้นขึ้นอยู่กับประเภทและรูปแบบของไฟล์ที่คุณเปรียบเทียบ
หากไฟล์ที่คุณกำลังเปรียบเทียบเป็นไฟล์ข้อความที่เรียงลำดับเครื่องมือ GNU ที่เขียนโดย Richard Stallman และ Davide McKenzie ที่เรียกว่าcomm
อาจทำการกรองที่คุณอยู่ มันเป็นส่วนหนึ่งของ coreutils
สมมติว่าคุณมี 2 ไฟล์ต่อไปนี้:
$ cat a
1
2
3
4
5
$ cat b
1
2
3
4
5
6
เส้นในไฟล์b
ที่ไม่ได้อยู่ในไฟล์a
:
$ comm <(sort a) <(sort b) -3
6
comm
; น่าเสียดายที่comm
ต้องมีไฟล์ที่จัดเรียง
<()
? มันใช้งานได้และฉันได้มันมา แต่มีชื่อแปลก ๆ นี้ไหม?
comm
ถูกเขียนขึ้นครั้งแรกประมาณปี 1973 โดยคนที่ Bell Labs ไม่ใช่ rms คุณหมายถึงการนำ GNU ไปใช้ซึ่งเกิดขึ้นในภายหลัง มีการใช้งานที่แตกต่างกันมากของยูทิลิตี้ Unix ในช่วงหลายปีที่ผ่านมา
จากstackoverflow ...
comm -23 file1 file2
-23 ไม่แสดงบรรทัดที่อยู่ในไฟล์ทั้งสองหรือเฉพาะในไฟล์ 2 ไฟล์จะต้องมีการเรียงลำดับ (อยู่ในตัวอย่างของคุณ) แต่ถ้าไม่ให้ไพพ์ไปตามการเรียงลำดับแรก ...
ดูหน้าคนที่นี่
วิธีการ grep และ comm (มีการเรียงลำดับ) ใช้เวลานานสำหรับไฟล์ขนาดใหญ่ SiegeX และ ghostdog74 แบ่งปันสองวิธี awkที่ยอดเยี่ยมสำหรับการแยกบรรทัดที่ไม่ซ้ำกันของหนึ่งในสองไฟล์บน Stack Overflow:
$ awk 'FNR==NR{a[$0]++}FNR!=NR && !a[$0]{print}' file1 file2
$ awk 'FNR==NR{a[$0]++;next}(!($0 in a))' file1 file2
หากไฟล์มีขนาดใหญ่และคุณไม่มีคำสั่งซื้อที่กำหนดเองสำหรับรายการของคุณ grep ใช้เวลานานเกินไป ทางเลือกที่รวดเร็วก็คือ
sort file1 > 1
sort file2 > 2
diff 1 2 | grep "\>" | sed -e 's/> //'
[file2-file1 ผลไปที่หน้าจอไปป์ที่ไฟล์ ฯลฯ ]
การเปลี่ยน>
เป็น<
จะได้รับการลบตรงกันข้ามrm 1 2
คุณยังสามารถพิจารณา vimdiff มันเน้นความแตกต่างระหว่างไฟล์ในโปรแกรมแก้ไขเป็นกลุ่ม