2013-06-08 42 views
6

Giả sử tôi có tệp này.phân loại với nhiều phím bằng lệnh sắp xếp Linux

$ cat a.txt 
c 1002 4 
f 1001 1 
d 1003 1 
a 1001 3 
e 1004 2 
b 1001 2 

Tôi muốn sắp xếp nó theo cột thứ hai và sau đó là cột thứ ba. Cột hai là số, trong khi cột 3 có thể được coi là chuỗi. Tôi biết lệnh sau hoạt động tốt.

$ sort -k2,2n -k3,3 a.txt 
f 1001 1 
b 1001 2 
a 1001 3 
c 1002 4 
d 1003 1 
e 1004 2 

Tuy nhiên, tôi nghĩ rằng sort -k2n a.txt cũng nên hoạt động, trong khi không.

$ sort -k2n a.txt 
a 1001 3 
b 1001 2 
f 1001 1 
c 1002 4 
d 1003 1 
e 1004 2 

Dường như nó sắp xếp theo cột hai, sau đó theo cột một thay vì cột ba. Tại sao chuyện này đang xảy ra? Nó có phải là một lỗi hay không? Nguyên nhân sort -k2 a.txt hoạt động ok với dữ liệu ở trên vì những con số này chỉ là chiều rộng cố định.

Phiên bản sắp xếp của tôi là sort (GNU coreutils) 8.15 trong cygwin.

+0

Thú vị. 'sort -k2 a.txt' sẽ hoạt động trong trường hợp * this *. '-k2' yêu cầu nó sắp xếp bằng cách sử dụng một khóa bắt đầu ở trường 2 và tiếp tục đến cuối dòng. '-k2n' yêu cầu nó sắp xếp trường 2 theo thứ tự số; điều đó có nghĩa là khóa sắp xếp kết thúc khi gặp phải khoảng trắng giữa các trường 2 và 3. Có thể là một ý tưởng hay khi dán phiên bản sắp xếp của bạn vào câu hỏi ở đâu đó. –

+0

Sử dụng 'sort (GNU coreutils) 8.5' Tôi có thể tạo lại hành vi được mô tả trên Debian ổn định. – alk

+0

@ MikeSherrill'Catcall 'Khi bạn cố gắng sắp xếp một giá trị không phải là số, sắp xếp (1) rơi trở lại phân loại chuỗi. '" 1001 3 "' vv bằng '-k2n' là * không * số. – PointedEars

Trả lời

9

Tôi thấy cảnh báo này trong số GNU sort docs.

Sắp xếp số trên trường thứ hai và giải quyết các mối quan hệ bằng cách sắp xếp theo thứ tự bảng chữ cái thứ ba và thứ tư của trường thứ năm. Sử dụng ‘:’ làm dấu phân tách trường.

 sort -t : -k 2,2n -k 5.3,5.4 

Lưu ý rằng nếu bạn đã viết -k 2n thay vì -k 2,2n loại sẽ phải sử dụng tất cả các ký tự bắt đầu trong lĩnh vực thứ hai và kéo dài đến cuối dòng là chìa khóa số chính. Đối với phần lớn các ứng dụng , việc xử lý các khóa bao gồm nhiều trường dưới dạng số sẽ không làm những gì bạn mong đợi.

Tôi không chắc điều gì kết thúc khi nó đánh giá '1001 3' dưới dạng khóa số, nhưng "sẽ không làm những gì bạn mong đợi" là chính xác. Có vẻ như rõ ràng rằng Quyền Điều cần làm là chỉ định từng khóa một cách độc lập.

Cùng một trang web nói điều này về cách giải quyết "quan hệ".

Cuối cùng, như một phương sách cuối cùng khi tất cả các phím so sánh bằng, sắp xếp so sánh toàn bộ dây chuyền như nếu không có tùy chọn đặt hàng khác hơn --reverse (-r) là quy định.

Tôi sẽ thú nhận rằng tôi hơi băn khoăn về cách diễn giải điều đó.

+0

Đoạn cuối cùng chắc chắn có nghĩa là, giá trị cho tất cả các khóa được chỉ định bằng nhau, sắp xếp (1) sử dụng so sánh chuỗi đơn giản trên các dòng và chỉ quan sát '--reverse' (hoặc' -r') nếu nó được chỉ định. Ví dụ, nếu có các dòng 'foo: 42: bar: baz: blabla' và' foo: 42: baz: bar: blabla', cái cũ được sắp xếp trước cái sau với các tùy chọn này vì '' bar ''< '" baz "' và ngược lại nếu bạn sử dụng '-r'. – PointedEars

+0

Cảm ơn nỗ lực của @ Mike. Tôi nghĩ rằng các tài liệu sắp xếp giải thích một số. Chúng ta chỉ nên cẩn thận về việc xử lý các khóa bao trùm nhiều trường dưới dạng số. – yejinxin

+0

@PointedEars: Điều đó sẽ giải thích được hành vi, tôi nghĩ vậy. Sắp xếp theo khóa đầu tiên, sau đó theo toàn bộ dòng. Toàn bộ dòng, tất nhiên, bắt đầu với trường đầu tiên. –

Các vấn đề liên quan