Làm cách nào để sắp xếp chuỗi kết hợp với chuỗi + số bằng cách sử dụng tập lệnh bash?


27

Đây là dữ liệu tôi muốn sắp xếp. Nhưng sortxử lý số thành chuỗi, dữ liệu không được sắp xếp như tôi mong đợi.

/ home / files / profile1
/ home / files / profile10
/ home / files / profile11
/ home / files / profile12
/ home / files / profile14
/ home / files / profile15
/ home / files / profile16
/ home / files / PROFILE2
/ home / files / profile3
/ home / files / profile4
/ home / files / profile5
/ home / files / profile6
/ home / files / profile7
/ home / files / profile8
/ home / files / profile9

Tôi muốn sắp xếp cái này để,

/ home / files / profile1
/ home / files / PROFILE2
/ home / files / profile3
/ home / files / profile4
/ home / files / profile5
/ home / files / profile6
/ home / files / profile7
/ home / files / profile8
/ home / files / profile9
/ home / files / profile10
/ home / files / profile11
/ home / files / profile12
/ home / files / profile14
/ home / files / profile15
/ home / files / profile16

Có một cách tốt bằng bash script? Tôi không thể sử dụng tập lệnh ruby ​​hoặc python ở đây.


thử sử dụng "sort
-nd

1
@bobah, "sort: tùy chọn` -dn 'không tương thích "
maxschlepzig

10
sort -Vsẽ làm.
Thor

2
@Thor. bình luận của bạn sẽ làm cho một câu trả lời tốt
Peter.O

Câu trả lời:


21

Bạn có thể sử dụng một ký tự canh gác tạm thời để phân định số:

$ sed 's/\([0-9]\)/;\1/' log | sort -n -t\; -k2,2 | tr -d ';'

Ở đây, ký tự sentinel là ';' - nó không phải là một phần của bất kỳ tên tệp nào bạn muốn sắp xếp - nhưng bạn có thể trao đổi ';' với bất kỳ nhân vật nào bạn thích. Bạn phải thay đổi sed, sorttrmột phần sau đó cho phù hợp.

Đường ống hoạt động như sau: sedLệnh chèn sentinel trước bất kỳ số nào, sortlệnh diễn giải sentinel là dấu phân cách trường, sắp xếp với trường thứ hai là khóa sắp xếp số và trlệnh sẽ xóa lại sentinel.

logbiểu thị tệp đầu vào - bạn cũng có thể dẫn đầu vào của mình vào sed.


Tôi thích cách bạn giải quyết vấn đề :)
SHW

44

Điều này rất giống với câu hỏi này . Vấn đề là bạn có một trường chữ và số mà bạn đang sắp xếp và -nkhông xử lý nó một cách hợp lý, tuy nhiên phiên bản sort ( -V) thì có. Do đó sử dụng:

sort -V

Lưu ý rằng tính năng này hiện được hỗ trợ bởi các triển khai sắp xếp GNU, FreeBSD và OpenBSD.


Bạn có biết làm thế nào là di động này? Tùy chọn này dường như không phải là một phần của thông số POSIX.
Ernest A

@ErnestA: Bạn nói đúng, đây là giải pháp cụ thể của GNU. Đã thêm một ghi chú.
Thor

@ErnestA: Tôi có vẻ như FreeBSD và OpenBSD đã thêm tính năng này.
Thor

Và nó không hoạt động nếu các số có tiền tố khác nhau.
Dante

1
Đối với bất kỳ độc giả: Lưu ý rằng đây là VỐN VỐN! Sử dụng sort -Vkhông sort -v. Thật khó để nói từ cái nhìn đầu tiên.
Gabriel Staples

7

Nếu tất cả các tên tệp của bạn có cùng một tiền tố trước phần số cuối cùng, hãy bỏ qua nó khi sắp xếp:

sort -k 1.20n

(20 là vị trí của chữ số đầu tiên. Đó là một chữ số cộng với độ dài /home/files/profile.)

Nếu bạn có một số phần không phải là số khác nhau, hãy chèn một sentinel .

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.