Sắp xếp tệp CSV theo mức độ ưu tiên của cột bằng lệnh "sắp xếp"


91

Tôi có một tệp csv và tôi muốn sắp xếp nó theo mức độ ưu tiên của cột, như "sắp xếp theo". Ví dụ:

3;1;2
1;3;2
1;2;3
2;3;1
2;1;3
3;2;1

Nếu tình huống này là kết quả của một "select", thì "order by" sẽ như sau: order theo column2, column1, column3 - kết quả sẽ là:

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1

Tôi muốn biết cách nhận được kết quả tương tự bằng cách sử dụng lệnh "sort" trên Unix.


4
Bằng cách này, đó là một tập tin SSV (dấu chấm phẩy tách giá trị): P
John Strood

Câu trả lời:


153
sort --field-separator=';' --key=2,1,3

8
Nếu các giá trị là số, thì bạn có thể muốn xem xét sử dụng -ntùy chọn sẽ "so sánh theo giá trị số chuỗi" hoặc -gtùy chọn "so sánh theo giá trị số chung". So sánh chuỗi các giá trị số sẽ nhận được các số có thứ tự như 1,10,2,20. Ít nhất đó là những tùy chọn có sẵn trên phiên bản sắp xếp của tôi trên CentOS. Bạn nên xác minh với trang người đàn ông các tùy chọn chính xác trên phiên bản sắp xếp của bạn.
Adam Porad

4
Tôi nhận đượcsort: stray character in field spec: invalid field specification ‘2,1,3’
Martin Thoma

3
Tuy nhiên, sort --field-separator=',' -r -k3 -k1 -k2 source.csv > target.csvđã làm việc cho tôi.
Martin Thoma

6
@MartinThoma đã lâu nhưng tôi gặp sự cố của bạn và tôi đã tìm thấy điều đó sort --field-separator=';' --key={2,1,3}. Điều này hoạt động GNU coreutils 8.4từ tháng 4 năm 2016
mrbolichi

2
@mrbolichi ký hiệu --key={2,1,3}sử dụng mở rộng dấu ngoặc
nhọn

28

Giả sử bạn có một hàng khác 3;10;3trong unsorted.csvtệp của mình . Sau đó, tôi đoán bạn mong đợi một kết quả được sắp xếp theo số:

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1
3;10;3

và không được sắp xếp theo thứ tự bảng chữ cái:

2;1;3
3;1;2
3;10;3
1;2;3
3;2;1
1;3;2
2;3;1

Để có được điều đó, bạn phải sử dụng -n:

sort --field-separator=';' -n -k 2,2 -k 1,1 -k 3,3 unsorted.csv

Điều đáng nói là 2,2đã được sử dụng. Nếu chỉ 2được sử dụng, thì sortlấy chuỗi từ đầu trường 2 đến cuối. 2,2đảm bảo rằng trường duy nhất 2được sử dụng.


7
Con trỏ chỉ ra sự khác biệt giữa -k 2 và -k 2,2 là đáng kể! Tôi đã bỏ qua điều này trong lần đọc trang đầu tiên của tôi. Cảm ơn.
usonianhorizon

Tôi đã thêm một vài dòng thêm, 3;10;3, 3:10:5, 3:10;2, 3;10;3theo thứ tự trong file nguồn, và khi sử dụng chỉ -k 2,2 nó xuất hiện để sắp xếp vào cột 2 và 3. Các trang người đàn ông nói "The -k option may be specified multiple times, in which case subsequent keys are compared when earlier keys compare equal.". Trong trường hợp của tôi, khóa trước đó (giá trị = 10) đã so sánh bằng nhau, tuy nhiên, tôi không chỉ định -knhiều lần. Tôi không chắc đây là hành vi đáng tin cậy hay liên quan đến hệ thống của tôi (mac). Cuối cùng thì điều đó cũng không thành vấn đề, miễn là cách sắp xếp chính là chính xác.
Davos

Ồ, tôi thấy cũng có -scách sắp xếp ổn định bỏ qua các phím bằng nhau, theo con người thì rõ ràng là nhanh hơn.
Davos

24

Câu trả lời của Charlie ở trên không phù hợp với tôi trên Cygwin (sắp xếp phiên bản 2.0, văn bản GNU), câu trả lời sau đã làm được:

sort -t"," -k2 -k1 -k1

3
Cygwin có phiên bản sắp xếp cũ hơn. Như mọi khi, trang người đàn ông là bạn của bạn.
Charlie Martin

2
Tôi đồng ý với @CharlieMartin, bạn nên kiểm tra trang người đàn ông trên hệ thống của mình. Trên CentOS tôi đã sử dụngsort --field-separator=';' -k2 -k1 -k3 test.csv
Adam Porad

-6

..và nếu ai đó đã làm theo giải pháp 'sắp xếp' nhưng bây giờ muốn nhận được nhiều hơn mục nhập duy nhất trên mỗi dòng (tức là số X hàng đầu của các mục nhập duy nhất), khi bạn đã sắp xếp tệp bằng cách sử dụng 'sắp xếp', bạn có thể sử dụng một ứng dụng nhỏ mà tôi đã tạo ở đây:

https://github.com/danieliversen/MiscStuff/blob/master/scripts/findTopUniques.java


2
Tốt cho bạn! Nhưng trong trường hợp của bạn, bạn có thể chỉ cần sử dụng cat unsorted-file | sort | uniq | head -X- Xsố hàng đầu tiên bạn muốn xuất là khi nào.
Slavik Meltser,

@SlavikMe Cảm ơn rất nhiều vì nhận xét! Tuy nhiên, đề xuất của bạn cho một kết quả khác .. Đề xuất của bạn nhận X dòng đầu tiên trong tệp được sắp xếp hoàn toàn, trong khi chúng tôi muốn nhận X dòng đầu tiên cho mỗi "khóa" (tức là nếu bạn có CSV có tên, thì nếu bạn sắp xếp bởi cột 2 "họ" thì các lệnh của bạn có thể chỉ nhận được 3 dòng với "Allen" là họ trong khi của chúng ta sẽ nhận được "Allen", "Brittain", "Charles", v.v.). Cảm ơn mặc dù!
Daniel Iversen

6
bạn sai rồi. Tôi khuyên bạn nên thử lệnh tôi đã viết trước khi nhận xét. Lưu ý rằng có một lệnh uniqtheo thứ tự đường ống, giữa dấu sorthead, mang lại tính duy nhất cho tất cả các hàng được sắp xếp ngay trước khi trích xuất các hàng trên cùng.
Slavik Meltser
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.