Làm thế nào để tôi thực hiện ls sắp xếp các ký tự gạch dưới trước?


20

Tôi thích có thể đặt tên tệp và thư mục với tiền tố gạch dưới nếu đó là thứ tôi muốn tách biệt khỏi các tệp và thư mục khác ở cùng cấp. Ví dụ, trên Windows và Mac, tiền tố một tệp có dấu gạch dưới sắp xếp nó lên trên cùng, phía trước các tệp bắt đầu bằng một ký tự chữ và số.

Google của tôi đã bật lên rằng nó phải làm với LC_COLLATE và ngôn ngữ hiện tại của tôi (en_US). Điều đó tốt, mặc dù tôi thực sự không hiểu tại sao en_US không sắp xếp như mong đợi.

Dựa trên vị trí cài đặt trang trình diễn ICU Collate thành en_US_POSIX chắc chắn dường như có thứ tự sắp xếp mà tôi đang tìm kiếm (bạn phải chỉnh sửa dữ liệu mẫu và thêm một số dấu gạch dưới để kiểm tra). Nhưng tôi không thực sự thấy cách áp dụng điều này trong vỏ Linux của mình.

Lý tưởng nhất là tôi muốn có thể thiết lập một cái gì đó trong cấu hình bash của mình để ls luôn sắp xếp các dấu gạch dưới trước. Tôi sẽ đi đâu để tới đó?


Tôi không thể sao chép bằng ICU Collate với mặc định hoặc với en_US_POSIX.txt thông qua "Tìm nạp quy tắc cho miền địa phương". Bạn có thể giải thích các cài đặt bạn đã sử dụng?
Mikel

Câu hỏi tương tự Askubfox.com/questions/47702/ Mạnh
Mikel

@Mikel sử dụng liên kết tôi đã cung cấp ở trên, thêm một số dấu gạch dưới vào dữ liệu thử nghiệm và sau đó gửi để xem kết quả sắp xếp.
Tom Auger

Đó chính xác là những gì tôi đã làm và các chuỗi bắt đầu bằng dấu gạch dưới được sắp xếp ở giữa thay vì bắt đầu, như thể các dấu gạch dưới không có ở đó.
Mikel

1
Một câu hỏi liên quan, liên quan đến việc thực sự thay đổi định nghĩa thứ tự đối chiếu, là unix.stackexchange.com/questions/421908 .
JdeBP

Câu trả lời:


5

Nếu bạn không thể lssắp xếp theo cách bạn muốn, hãy thử mở rộng shell.

Bạn có thể sử dụng các mẫu tên tệp để chạy lsvới danh sách các tệp mà trình bao đã sắp xếp, bỏ qua phương thức lssử dụng.

ls -lf _* [!_]*

Giả sử bạn có các tập tin

_a a _b b _c c

điều này giống như chạy

ls -lf _a _b _c a b c

Giải trình:

_* là một mẫu vỏ khớp với bất kỳ tên tệp nào bắt đầu bằng dấu gạch dưới, được mở rộng theo thứ tự chữ cái.

[!_]*khớp với bất kỳ tên tệp nào không bắt đầu bằng dấu gạch dưới, được mở rộng theo thứ tự chữ cái.

-fnói lsđể không sắp xếp, vì vỏ đã làm.

Thêm thông tin: mở rộng tên tệp bash

Nếu có thư mục trong thư mục hiện tại, bạn sẽ muốn chạy lệnh như thế này để tránh ls liệt kê các tệp trong thư mục:

ls -lfd _* [!_]*

7
Nhân tiện, DOS / Windows / OSX không thực sự đặt dấu gạch dưới trước bất kỳ thứ gì khác: chúng sắp xếp không phân biệt chữ hoa chữ thường với dấu gạch dưới đặt trước các chữ cái, nhưng một số ký tự dấu chấm câu khác đi trước hoặc sau dấu gạch dưới. Sử dụng _để làm cho các tệp xuất hiện đầu tiên là một hack dành riêng cho hệ điều hành; và phiên bản unix của bản hack này là để bắt đầu tên tệp bằng chữ in hoa: quy ước unix mặc định là chỉ sử dụng các chữ cái viết thường trong tên tệp.
Gilles 'SO- đừng trở nên xấu xa'

4
Hoặc số không; ví dụ 00README.
mattdm

1
@Gilles +1 cho cách thực hành tốt nhất unix sử dụng mũ trên các tệp quan trọng để làm cho chúng là đầu tiên. Vào cuối ngày, nếu đó là quy ước, có lẽ tốt nhất là tôi đơn giản chấp nhận điều đó, thay vì cố gắng buộc unix hành xử theo cách mà các HĐH khác làm để tôi có thể sử dụng các quy ước được phát triển cho Mac hoặc Windows. Cám ơn về tiền bo nhiều.
Tom Auger

1
@TomAuger -fnói lskhông nên tự sắp xếp, vì vậy nó sẽ hiển thị các đối số của nó theo thứ tự chúng được thông qua. Kết quả của mỗi lần mở rộng ký tự đại diện _*[!_]*là một danh sách được sắp xếp theo từ vựng.
Gilles 'SO- ngừng trở nên xấu xa'

1
@TomAuger Các đối số lsđược sắp xếp (theo hai nhóm: các đối số bắt đầu bằng _, sau đó là các đối số khác) khi chúng được tạo bởi trình bao. Chạy echo ls -lf _* [!_]*để xem những gì xảy ra. Các -flá cờ nói lskhông làm bất cứ phân loại.
Gilles 'SO- đừng trở nên xấu xa'

16

Nếu bạn không quan tâm đến việc trộn chữ thường và chữ hoa, hãy đặt ngôn ngữ của bạn thành Cký tự theo thứ tự số. _rơi giữa chữ hoa và chữ thường

$ LC_COLLATE=C ls    
BAR  FOO  _score  _under  hello  world
$ LC_COLLATE=en_US ls                    
BAR  FOO  hello  _score  _under  world

Các cài đặt LC_MESSAGESngôn ngữ (ngôn ngữ của thông báo lỗi), LC_CTYPE(bộ ký tự) và LC_TIME(định dạng ngày và giờ) rất hữu ích. LC_COLLATELC_NUMERICthường rắc rối hơn giá trị của chúng, tôi không khuyên bạn nên đặt chúng. Sắp xếp từ vựng đúng cách phức tạp hơn mức LC_COLLATEđược chỉ định và nó có thể gây ra tất cả các loại hành vi kỳ lạ khi bạn sử dụng phạm vi ký tự trong các biểu thức thông thường. LC_NUMERICchủ yếu là mỹ phẩm, ngoại trừ khi có sự cố khủng khiếp vì một số chương trình đã tạo ra một số có dấu phân cách khác ..


+1 Rất thú vị. Vì vậy, bằng cách sử dụng biểu mẫu này, bạn đang tạm thời đặt biến môi trường LC_COLLATE chỉ cho một phiên bản ls đó? Có đúng không?
Tom Auger

1
Bất kỳ cách nào để làm cho dấu gạch dưới xuất hiện TRƯỚC các chữ in hoa?
Tom Auger

1
@TomAuger Vâng, VAR=value cmdbộ VARđể valuechỉ trong môi trường của cmdvà không chạm vào giá trị (hay vắng mặt của giá trị) trong vỏ nơi bạn chạy nó. Để làm cho dấu gạch dưới xuất hiện trước chữ hoa, bạn sẽ cần xác định cài đặt ngôn ngữ của riêng bạn. Điều này là có thể, nhưng rất khó sử dụng, vì ít nhất là trong Linux, thư viện tiêu chuẩn chỉ tìm các định nghĩa miền địa phương /usr/lib/locale- không có ~/.localehoặc biến môi trường nơi bạn có thể đặt en_tomcài đặt của mình .
Gilles 'SO- ngừng trở nên xấu xa'

@TomAuger Nếu đây chỉ là về lslệnh, hãy đi với đề xuất của Mikel .
Gilles 'SO- ngừng trở nên xấu xa'

2

Thật không may, Linux sử dụng glibc cho thông tin ngôn ngữ của mình chứ không phải ICU, vì vậy không có cách nào để áp dụng trực tiếp điều này cho Linux mà không tốn nhiều công sức hoặc bổ sung ICU vào glibc hoặc bổ sung thông tin ngôn ngữ trong glibc.


-4

Thêm công -ftắc (không sắp xếp) làm cho nó hiển thị theo cách đó cho tôi.

man ls

[root@dusknoir ~/java/test]# ls -fl
total 0
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _1
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _2
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _3
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 1
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 2
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 3

6
Chỉ vì đó là cách chúng được lưu trữ trong hệ thống tập tin.
Ignacio Vazquez-Abrams

3
Xin lỗi, nhưng câu trả lời này là sai. Kiểm tra: touch 3 1 _1 _3 2 _2 && ls -flđầu ra2 . 1 3 _2 _3 .. _1
Marco
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.