Kiểm tra tất cả các dòng của một tệp là duy nhất


11

Tôi có một tệp văn bản chứa các dòng như thế này:

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

Làm thế nào tôi có thể chắc chắn về tính độc đáo của mỗi dòng?

LƯU Ý: Mục tiêu là kiểm tra tệp, không sửa đổi tệp nếu có dòng trùng lặp.



1
Bạn có muốn kiểm tra xem tất cả các dòng là duy nhất hay bạn muốn xóa bất kỳ bản sao nào?
8bittree

1
@ 8bittree - muốn chắc chắn sự độc đáo
snr

Câu trả lời:


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

Chính xác những gì tôi đã nói, ngoại trừ uniqthay vìsort -u
Nonny Moose

1
Nếu đầu vào chưa được sắp xếp, uniqsẽ là một sai lầm lớn; nó chỉ lặp lại các dòng liền kề!
alexis

1
Nếu một người quan tâm đến thủ phạm, người sort <file> | uniq -dta sẽ in các bản sao.
Rolf

25

Giải pháp Awk:

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

4
+1 Câu trả lời được chấp nhận đọc qua toàn bộ tệp hai lần, trong khi câu trả lời này dừng lại ngay khi nó gặp một dòng trùng lặp trong một lần đọc. Điều này cũng sẽ làm việc với đầu vào đường ống, trong khi các nhu cầu khác mà nó có thể đọc lại.
JoL

Bạn không thể đẩy echovào END?
Ignacio Vazquez-Abrams

2
@ IgnacioVazquez-Abrams Thực sự không có điểm nào trong tiếng vang. Làm && echohoặc || echolà một quy ước trong các câu trả lời để chỉ ra rằng một lệnh thực hiện đúng với mã trạng thái thoát. Điều quan trọng là exit(1). Lý tưởng nhất là bạn sẽ sử dụng như thế này if has_only_unique_lines file; then ...chứ không phải if [[ $(has_only_unique_lines file) = "no dupes" ]]; then ...là ngớ ngẩn.
JoL

2
Trường hợp các câu trả lời khác đọc tệp hai lần để lưu bộ nhớ, điều này sẽ đọc toàn bộ tệp vào bộ nhớ, nếu không có bản sao.
Kusalananda

1
@Kusalananda Mặc dù điều này sẽ đọc toàn bộ tệp vào bộ nhớ khi không có bản sao, sử dụng sortcũng sẽ, bất kể có bản sao hay không, phải không? Làm thế nào là tiết kiệm bộ nhớ?
JoL

21

Sử dụng sort/ uniq:

sort input.txt | uniq

Để chỉ kiểm tra các dòng trùng lặp, hãy sử dụng -dtùy chọn cho uniq. Điều này sẽ chỉ hiển thị các dòng trùng lặp, nếu không nó sẽ không hiển thị:

sort input.txt | uniq -d

Đây là goto của tôi. Không chắc chắn những gì khác, câu trả lời được bình chọn cao hơn cung cấp mà câu trả lời này không.
dùng1717828

1
Đó là lựa chọn tốt để loại bỏ trùng lặp.
snr

1
Đây không phải là những gì anh ấy muốn. Anh ta muốn biết nếu có bản sao, không loại bỏ chúng.
Barmar

@Barmar: Mặc dù có vẻ như vậy nhưng câu hỏi vẫn chưa rõ ràng. Cũng như bình luận của OP cố gắng làm rõ nó.
jlie_b

Có một chỉnh sửa đang chờ xử lý để thêm rõ ràng hơn.
Barmar

5

TLD

Câu hỏi ban đầu không rõ ràng và đọc rằng OP chỉ muốn một phiên bản duy nhất của nội dung của một tệp. Điều đó được hiển thị dưới đây. Trong dạng cập nhật của câu hỏi, OP hiện đang tuyên bố rằng anh ấy / cô ấy chỉ muốn biết liệu nội dung của tệp có phải là duy nhất hay không.


Kiểm tra xem nội dung của tệp có duy nhất hay không

Bạn chỉ có thể sử dụng sortđể xác minh xem một tệp là duy nhất hoặc chứa các bản sao như vậy:

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

Thí dụ

Nói rằng tôi có hai tệp này:

tập tin mẫu trùng lặp
$ 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
tập tin mẫu duy nhất
$  cat uniq_input.txt
A
B
C
D

Bây giờ khi chúng tôi phân tích các tệp này, chúng tôi có thể biết chúng là duy nhất hoặc chứa các bản sao:

kiểm tra trùng lặp tập tin
$ sort -uC dup_input.txt && echo "unique" || echo "duplicates"
duplicates
kiểm tra tập tin duy nhất
$ sort -uC uniq_input.txt && echo "unique" || echo "duplicates"
unique

Câu hỏi gốc (nội dung duy nhất của tệp)

Có thể được thực hiện chỉ với 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

Tôi thường sortlà tập tin, sau đó sử dụng uniqđể đếm số lượng trùng lặp, sau đó tôi sortlại thấy các bản sao ở cuối danh sách.

Tôi đã thêm một bản sao vào các ví dụ bạn cung cấp:

$ 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

Vì tôi chưa đọc trang người đàn ông uniqtrong một lúc, tôi đã xem nhanh mọi lựa chọn thay thế. Điều sau đây loại bỏ sự cần thiết cho loại thứ hai, nếu bạn chỉ muốn xem các bản sao:

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

Đó thực sự là một sự thay thế tốt. #rez
snr

2

Nếu không có trùng lặp, tất cả các dòng là duy nhất:

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

Mô tả: Sắp xếp các dòng tệp để tạo các dòng lặp lại liên tiếp (sắp xếp)
Trích xuất tất cả các dòng liên tiếp bằng nhau (uniq -d).
Nếu có bất kỳ đầu ra nào của lệnh trên ( [...]), thì ( &&) in một thông báo.


2

Điều này sẽ không được hoàn thành nếu không có câu trả lời Perl!

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

Điều này sẽ in mỗi dòng không duy nhất một lần: vì vậy nếu nó không in gì, thì tệp có tất cả các dòng duy nhất.


1

Sử dụng cmpsorttrong bash:

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

hoặc là

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

Điều này sẽ sắp xếp các tập tin hai lần, giống như câu trả lời được chấp nhận.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.