ตรวจสอบไฟล์ทุกบรรทัดว่าไม่ซ้ำใคร


11

ฉันมีไฟล์ข้อความที่มีบรรทัดเช่นนี้:

This is a thread  139737522087680
This is a thread  139737513694976
This is a thread  139737505302272
This is a thread  139737312270080
.
.
.
This is a thread  139737203164928
This is a thread  139737194772224
This is a thread  139737186379520

ฉันจะมั่นใจได้ถึงความมีเอกลักษณ์ของทุกบรรทัดได้อย่างไร

หมายเหตุ:เป้าหมายคือเพื่อทดสอบไฟล์ไม่ใช่เพื่อแก้ไขหากมีบรรทัดที่ซ้ำกันอยู่


1
เชื่อมโยงใน: unix.stackexchange.com/q/76049/117549
Jeff Schaller

1
คุณต้องการตรวจสอบว่าทุกบรรทัดมีลักษณะเฉพาะหรือไม่หรือต้องการลบรายการที่ซ้ำกันออกหรือไม่?
8bittree

1
@ 8bittree - หวังว่าจะได้รับความเป็นเอกลักษณ์
snr

คำตอบ:


24
[ "$(wc -l < input)" -eq "$(sort -u input | wc -l)" ] && echo all unique

สิ่งที่ผมจะได้กล่าวยกเว้นกับuniqแทนsort -u
Nonny Moose

1
หากอินพุตยังไม่ได้จัดเรียงuniqจะเป็นความผิดพลาดครั้งใหญ่ มันจะลดความซ้ำซ้อนของบรรทัดที่อยู่ติดกัน!
alexis

1
หากใครสนใจผู้กระทำผิดsort <file> | uniq -dก็จะพิมพ์รายการที่ซ้ำกัน
Rolf

25

วิธีแก้ปัญหา awk:

awk 'a[$0]++{print "dupes"; exit(1)}' file && echo "no dupes"

4
+1 คำตอบที่ได้รับการยอมรับจะอ่านผ่านไฟล์ทั้งหมดสองครั้งขณะที่คำตอบจะหยุดทันทีที่พบบรรทัดที่ซ้ำกันในการอ่านครั้งเดียว สิ่งนี้จะทำงานกับอินพุต piped ในขณะที่ไฟล์อื่นต้องการไฟล์ที่สามารถอ่านซ้ำได้
JoL

คุณไม่สามารถechoเข้าไปข้างในENDหรือ
Ignacio Vazquez-Abrams

2
@ IgnacioVazquez-Abrams ไม่มีเสียงสะท้อน การทำ&& echoหรือ|| echoเป็นแบบแผนในการตอบเพื่อระบุว่าคำสั่งทำสิ่งที่ถูกต้องด้วยรหัสสถานะการออก exit(1)สิ่งที่สำคัญคือ เป็นการดีที่คุณจะใช้เช่นนี้if has_only_unique_lines file; then ...ไม่if [[ $(has_only_unique_lines file) = "no dupes" ]]; then ...ว่าจะโง่
JoL

2
ในกรณีที่คำตอบอื่น ๆ อ่านไฟล์สองครั้งเพื่อบันทึกความจำการดำเนินการนี้จะอ่านไฟล์ทั้งหมดในหน่วยความจำหากไม่มีการซ้ำซ้อน
Kusalananda

1
@Kusalananda ในขณะนี้จะอ่านไฟล์ทั้งหมดลงในหน่วยความจำเมื่อไม่มีการใช้งานซ้ำซ้อนการใช้งานsortก็เช่นกันไม่ว่าจะมีการทำงานแบบสองทางหรือไม่ใช่ไหม? หน่วยความจำที่บันทึกไว้เป็นอย่างไร?
JoL

21

ใช้sort/ uniq:

sort input.txt | uniq

ในการตรวจสอบเฉพาะบรรทัดที่ซ้ำกันให้ใช้-dตัวเลือกสำหรับ uniq การทำเช่นนี้จะแสดงเฉพาะบรรทัดที่ซ้ำกันหากไม่มีจะไม่แสดงสิ่งใด:

sort input.txt | uniq -d

นี่คือ goto ของฉัน ไม่แน่ใจว่าคำตอบที่ได้รับการโหวตสูงกว่าอื่นคืออะไร
user1717828

1
เป็นทางเลือกที่ดีในการลบรายการที่ซ้ำ
snr

1
นี่ไม่ได้ทำสิ่งที่เขาต้องการ เขาต้องการทราบว่ามีรายการที่ซ้ำกันหรือไม่ไม่ลบออก
Barmar

@Barmar: ในขณะที่ดูเหมือนว่าวิธีการที่คำถามยังไม่ชัดเจน เช่นเดียวกับความคิดเห็น OPs พยายามที่จะชี้แจง
jesse_b

มีการแก้ไขที่รอดำเนินการซึ่งเพิ่มความกระจ่างมากขึ้น
Barmar

5

TLDR

คำถามเดิมไม่ชัดเจนและอ่านว่า OP ต้องการเนื้อหาเนื้อหาของไฟล์ที่ไม่ซ้ำใคร ที่แสดงด้านล่าง ในรูปแบบคำถามที่อัปเดตตั้งแต่ตอนนี้ OP กำลังระบุว่าเขา / เธอต้องการทราบว่าเนื้อหาของไฟล์นั้นไม่เหมือนใครหรือไม่


ทดสอบว่าเนื้อหาของไฟล์ไม่ซ้ำกันหรือไม่

คุณสามารถใช้sortเพื่อยืนยันว่าไฟล์นั้นมีลักษณะเฉพาะหรือมีสิ่งที่ซ้ำซ้อนดังนี้

$ sort -uC input.txt && echo "unique" || echo "duplicates"

ตัวอย่าง

ว่าฉันมีสองไฟล์เหล่านี้:

ไฟล์ตัวอย่างที่ซ้ำกัน
$ cat dup_input.txt
This is a thread  139737522087680
This is a thread  139737513694976
This is a thread  139737505302272
This is a thread  139737312270080
This is a thread  139737203164928
This is a thread  139737194772224
This is a thread  139737186379520
ไฟล์ตัวอย่างที่ไม่ซ้ำกัน
$  cat uniq_input.txt
A
B
C
D

ตอนนี้เมื่อเราวิเคราะห์ไฟล์เหล่านี้เราสามารถบอกได้ว่ามันมีลักษณะเฉพาะหรือมีสิ่งที่ซ้ำกัน:

ทดสอบไฟล์ที่ซ้ำกัน
$ sort -uC dup_input.txt && echo "unique" || echo "duplicates"
duplicates
ทดสอบไฟล์ที่ไม่ซ้ำ
$ sort -uC uniq_input.txt && echo "unique" || echo "duplicates"
unique

คำถามเดิม (เนื้อหาที่ไม่ซ้ำกันของไฟล์)

สามารถทำได้ด้วยเพียงแค่sort:

$ sort -u input.txt
This is a thread  139737186379520
This is a thread  139737194772224
This is a thread  139737203164928
This is a thread  139737312270080
This is a thread  139737505302272
This is a thread  139737513694976
This is a thread  139737522087680

3

ฉันมักจะsortเป็นไฟล์จากนั้นใช้uniqในการนับจำนวนที่ซ้ำกันแล้วฉันsortอีกครั้งดูที่ซ้ำกันที่ด้านล่างของรายการ

ฉันได้เพิ่มหนึ่งรายการซ้ำลงในตัวอย่างที่คุณให้ไว้:

$ sort thread.file | uniq -c | sort
      1 This is a thread  139737186379520
      1 This is a thread  139737194772224
      1 This is a thread  139737203164928
      1 This is a thread  139737312270080
      1 This is a thread  139737513694976
      1 This is a thread  139737522087680
      2 This is a thread  139737505302272

เนื่องจากฉันไม่ได้อ่าน man page มาuniqสักพักนึงฉันจึงมองหาทางเลือกอื่นอย่างรวดเร็ว ต่อไปนี้ช่วยลดความจำเป็นในการเรียงลำดับที่สองหากคุณต้องการเห็นรายการที่ซ้ำกัน:

$ sort thread.file | uniq -d
This is a thread  139737505302272

มันเป็นทางเลือกที่ดีอย่างแน่นอน #rez
snr

2

หากไม่มีการซ้ำซ้อนทุกบรรทัดจะไม่ซ้ำกัน:

[ "$(sort file | uniq -d)" ] && echo "some line(s) is(are) repeated"

คำอธิบาย: เรียงลำดับบรรทัดไฟล์เพื่อให้บรรทัดที่ซ้ำกันติดกัน (เรียงลำดับ)
แตกบรรทัดที่ต่อเนื่องทั้งหมดที่เท่ากัน (uniq -d)
หากมีเอาต์พุตใด ๆ ของคำสั่งด้านบน ( [...]) ดังนั้น ( &&) พิมพ์ข้อความ


2

สิ่งนี้จะไม่สมบูรณ์หากไม่มีคำตอบ Perl!

$ perl -ne 'print if ++$a{$_} == 2' yourfile

การดำเนินการนี้จะพิมพ์แต่ละบรรทัดที่ไม่ซ้ำกันหนึ่งครั้ง: ดังนั้นหากไม่พิมพ์อะไรเลยไฟล์จะมีบรรทัดที่ไม่ซ้ำกันทั้งหมด


1

การใช้cmpและsortในbash:

cmp -s <( sort file ) <( sort -u file ) && echo 'All lines are unique'

หรือ

if cmp -s <( sort file ) <( sort -u file )
then
    echo 'All lines are unique'
else
    echo 'At least one line is duplicated'
fi

สิ่งนี้จะเรียงลำดับไฟล์สองครั้งเหมือนคำตอบที่ยอมรับ

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