Sắp xếp lệnh không nhất quán hành vi


8

Tôi muốn sắp xếp hai tệp nhưng tôi không thể có kết quả nhất quán. Có vẻ như có vấn đề với đối chiếu nhưng tôi không thể hiểu lý do. Trong phân cách tệp mẫu là một khoảng trắng:

tập tin1:

a
b
B
A

tập tin 2:

a 1
b 0
B 1
A 0

Tôi sử dụng sort -k1,1để sắp xếp các tệp này và đầu ra là:

đã sắp xếp1:

a
A
b
B

đã sắp xếp2:

A 0
a 1
b 0
B 1

Tôi cần những tập tin được sắp xếp trong một joinvà hiện đang phàn nàn rằng một trong những tập tin không được sắp xếp.

Trong môi trường của tôi LC_COLLATELC_ALLkhông được đặt, LANGđược đặt thànhen_US.UTF-8

Với LC_ALL=C sort -k1,1đầu ra là:

đã sắp xếp11:

A
B
a
b

đã sắp xếp22:

A 0
B 1
a 1
b 0

Tôi không cần một đơn đặt hàng cụ thể, tôi chỉ muốn nó có thể tham gia kết quả. Cách này joinhoạt động. Để được an toàn tôi cũng có thể thêm vào trước joinvới LC_ALL=C.

Câu hỏi của tôi

Tại sao trong sorted1 atrước A và trong sorted2 asau A ? Dù đối chiếu là gì, nó dành cho cả hai sortlệnh và tôi đang sắp xếp dựa trên cột 1 giống hệt nhau trong cả hai tệp đầu vào.

Đã thêm đầu ra của ltrace -e strcoll

tập tin1

sort->strcoll("B","A") =1
sort->strcoll("a","b") =-1 
sort->strcoll("a","A") =-7
a
sort->strcoll("b","A") =1
A
sort->strcoll("b","B") =-7
b
B
+++ exited (status 0) +++

tập tin2

sort->strcoll("B 1","A 0") =1
sort->strcoll("a 1","b 0") =-1 
sort->strcoll("a 1","A 0") =1
A 0
sort->strcoll("a 1","B 1) =-1
a 1
sort->strcoll("b 0","B 1") =-1
b 0
B 1
+++ exited (status 0) +++

Không thể sao chép này, bạn đang sử dụng phiên bản sắp xếp nào?
123

@ User112638726, tôi đang sử dụng sort 8.22 trên centos 7
Ashkan

Kiểm tra xem bạn không có một số ký tự không thể in trong tệp, như thế nào \0. Ví dụ với recode us..dump file.
jimmij

1
LC_ALL=CDù sao join, bạn có thể muốn sử dụng , đặc biệt nếu tệp chứa các ký tự không phải ASCII vì tất cả các ngôn ngữ glibc UTF-8 đều có lỗi trong đó nhiều ký tự khác nhau và các thành phần đối chiếu giống nhau ở đó.
Stéphane Chazelas

4
Tôi có thể sao chép với sắp xếp trong rpm.pbone.net/index.php3/stat/4/idpl/26640824/dir/centos_7/com/ trộm , dường như bị phá vỡ hoàn toàn về vấn đề đó, không phải với cơ sở 8.22 từ gnu.org . Tôi có thể thấy một chiếc CentOS có một bản vá quốc tế hóa lớn có lẽ là thủ phạm. Bạn có thể muốn báo cáo đó là một lỗi cho CentOS nếu chưa được biết.
Stéphane Chazelas

Câu trả lời:


3

Như Stéphane Chazelas đã nói trong bình luận , đó là một lỗi trong việc triển khai cụ thể coreutils(trong coreutils-8.22-11.el7) của CentOS / Red Hat, cụ thể hơn là trong bản vá quốc tế hóa lỗi ( coreutils-i18n.patch) mà họ đã viết và áp dụng trên đầu GNU coreutils-8.22.

Tôi đã báo cáo nó ở đây cho CentOS và cả ở đây cho Red Hat. Nó đã được biết đến tại Red Hat và được sửa ở đó coreutils-8.22-13.el7.

Cái đó chưa có sẵn cho CentOS tại thời điểm này (2015-08-20).

Để đầy đủ, lưu ý rằng lỗi cũng (không chính xác là lỗi không có) đã báo cáo ngược dòng (tại GNU), nơi bạn sẽ tìm thấy thêm một số thông tin về nó.


1

Đối chiếu mặc định của bạn (en_US.UTF-8) gây ra điều này. Bạn nên đặt giá trị LC_COLLATE để đặt văn bản theo chỉ dẫn.

 LC_COLLATE='C' sort -k1 file1

1
Câu hỏi của tôi là tại sao đối chiếu mặc định của tôi hoạt động theo cách này? Một trong những điều này có thể đúng a is before Ahoặc a is after Akhông cả hai. Làm thế nào một kết quả đối chiếu trong cả hai?
Ashkan

Không sort -k1, sort -k1giống như sort. Nó sắp xếp trên phần của dòng bắt đầu từ trường đầu tiên, vì vậy về cơ bản là toàn bộ dòng. sort -k1,1để sắp xếp trên trường đầu tiên.
Stéphane Chazelas

@Ashkan Tôi nghĩ rằng một đối chiếu có thể tuyên bố điều đó Aabằng nhau. Lệnh sort sau đó sẽ sắp xếp theo các ký tự sau này trên dòng hoặc không thành công, để chúng theo thứ tự ban đầu chúng xuất hiện trong tệp. Ví dụ như ac, aa, Ab, nên được sắp xếp như aa, Ab, ac, không Ab, aa, achay aa, ac, Ab.
rjmunro
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.