Làm thế nào tôi có thể làm cho các trang web ls trước đây hiển thị dotfiles trong khi vẫn không phân biệt chữ hoa chữ thường?


21

Tạo các tập tin sau trong một thư mục.

$ touch .a .b a b A B 你好嗎

lsThứ tự mặc định của tôi bỏ qua sự hiện diện của các dấu chấm hàng đầu, xen kẽ chúng với các tệp khác.

$ ls -Al
total 0
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 A
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 B
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:06 你好嗎

Tôi có thể thay đổi LC_COLLATE để đặt dotfiles trước.

$ LC_COLLATE=C ls -Al
total 0
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 A
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 B
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:06 你好嗎

Thật không may, điều này làm cho thứ tự sắp xếp phân biệt chữ hoa chữ thường, tức là ABtrước ab. Có cách nào để in dotfiles trước trong khi không phân biệt chữ hoa chữ thường ( Aatrước Bb) không?

Chỉnh sửa: cố gắng sửa đổi LC_COLLATE

Không có câu trả lời nào cho đến nay sao chép đầy đủ chức năng của lsmột cách dễ dàng. Có thể hiểu được, tôi có thể bọc một số trong số chúng trong một hàm, nhưng điều này sẽ phải bao gồm một số mã chi tiết về (ví dụ) cách làm việc không có đối số so với việc cung cấp một thư mục làm đối số. Hoặc làm thế nào để đối phó với một -dcờ rõ ràng .

Ngoài ra, tôi nghĩ rằng có lẽ có thể LC_COLLATEsử dụng tốt hơn . Tuy nhiên, tôi dường như không thể làm cho công việc đó. Tôi hiện đang sử dụng LC_COLLATE="en_AU.UTF-8". Tôi đã kiểm tra /usr/share/i18n/locales/en_AU(mặc dù tôi không chắc đây có phải là tệp đúng không, vì tôi không thể thấy bất kỳ tài liệu tham khảo nào UTF-8); Tôi tìm thấy như sau.

LC_COLLATE
copy "iso14651_t1"
END LC_COLLATE

/usr/share/i18n/locales/iso14651_t1chứa copy "iso14651_t1_common". Cuối cùng, /usr/share/i18n/locales/iso14651_t1_commonchứa

 <U002E> IGNORE;IGNORE;IGNORE;<U002E> # 47 .

Tôi đã xóa dòng này, chạy sudo locale-genvà khởi động lại máy tính của tôi. Thật không may, điều này không thay đổi gì.

Câu trả lời:


11

OP đã rất gần với chỉnh sửa /usr/share/i18n/locales/iso14651_t1_common, nhưng mẹo là không xóa dòng

<U002E> IGNORE;IGNORE;IGNORE;<U002E> # 47 .

mà là sửa đổi nó thành

<U002E> <RES-1>;IGNORE;IGNORE;<U002E> # 47 .

Tại sao điều này hoạt động

Các IGNORE tuyên bố xác định rằng toàn bộ dừng (còn gọi là dấu chấm hoặc ký tự <U002E>) sẽ bị bỏ qua khi sắp xếp các từ theo thứ tự bảng chữ cái. Để làm cho các dotfiles của bạn xuất hiện đầu tiên, hãy đổi IGNOREthành biểu tượng đối chiếu xuất hiện trước tất cả các ký tự khác. Biểu tượng đối chiếu được xác định bởi các dòng như

collating-symbol <something-inside-angle-brackets>

và chúng được sắp xếp theo sự xuất hiện của dòng

<something-inside-angle-brackets>

Trong bản sao của tôi iso14651_t1_common, biểu tượng đối chiếu vị trí đầu tiên là <RES-1>, xuất hiện trên dòng 3458. Nếu tệp của bạn khác, hãy sử dụng biểu tượng đối chiếu nào được đặt hàng trước.

Chi tiết về thứ tự ký tự với LC_COLLATE

<U002E>có ba IGNOREcâu lệnh vì các chữ cái có thể được so sánh nhiều lần trong trường hợp quan hệ. Để hiểu điều này, hãy xem xét chữ thường avà chữ hoa A(là một phần của một nhóm các ký tự thực sự được so sánh bốn lần):

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A

Có nhiều vòng so sánh cho phép các tệp bắt đầu bằng "a" và "A" được nhóm lại với nhau vì cả hai được so sánh như <a>trong lần chuyển đầu tiên, với chữ cái tiếp theo xác định thứ tự. Nếu tất cả các chữ cái sau giống nhau (ví dụ a.txtA.txt), thì lần thứ ba sẽ đặt a.txtđầu tiên vì biểu tượng đối chiếu cho các chữ cái thường <MIN>xuất hiện trên dòng 3467, trước biểu tượng đối chiếu cho các chữ cái in hoa <CAP>(dòng 3488).

Thực hiện thay đổi này

Nếu bạn muốn giai đoạn đến trước mỗi khi chương trình đặt hàng các chữ cái bằng cách sử dụng LC_COLLATE, bạn có thể sửa đổi iso14651_t1_commonnhư được mô tả ở trên và xây dựng lại tệp vị trí của mình. Nhưng nếu bạn muốn thực hiện thay đổi này chỉ đểls và không có quyền truy cập root, bạn có thể sao chép các tệp bản địa gốc sang thư mục khác trước khi sửa đổi chúng.

Tôi đã làm gì

Locale mặc định của tôi là en_US, vì vậy tôi sao chép en_US, iso14651_t1iso14651_t1_commonđể $HOME/path/to/new/locales. Ở đó tôi thực hiện thay đổi nêu trên để iso14651_t1_commonvà đổi tên en_USđể en_DOTFILE. Tiếp theo tôi đã biên dịch miền địa phương en_DOTFILE với

localedef -i en_DOTFILE -f UTF-8 -vc $HOME/path/to/new/locales/en_DOTFILE.UTF-8

Để thay thế lsthứ tự mặc định , hãy tạo một tập lệnh BASH có tên ls:

#!/bin/bash
LOCPATH=$HOME/path/to/new/locales LANG=en_DOTFILE.UTF-8 ls "$@"

lưu nó ở đâu đó xuất hiện trước /usr/bintrên đường dẫn của bạn và làm cho nó có thể thực thi được chmod +x ls.


tất nhiên, bạn sẽ phải thêm -a hoặc -A để xem các dotfiles của mình, nhưng trừ khi bạn luôn muốn nhìn thấy chúng, sẽ rất hợp lý khi thực hiện điều đó trên dòng lệnh, không phải trong tập lệnh BASH của bạn
beandip

Rực rỡ! Cảm ơn bạn, điều này là hoàn hảo! Tôi vừa sửa đổi tệp sở hữu gốc, vì vậy tôi đã không kiểm tra tập lệnh của bạn. Tuy nhiên, tôi nghĩ rằng bạn cần phải đặt dấu ngoặc kép xung quanh bạn $@.
Sparhawk

cuộc gọi tốt - báo giá kép được thêm vào
beandip

11

Bạn có thể sử dụng thứ tự sắp xếp của vỏ thay vì (có thể không liên quan đến của miền địa phương để đối chiếu; bash, AT & T ksh, yash, tcshzshcung cấp cho các kết quả mong đợi, mkshdash. Không fishdường như để cho một trường hợp để không nhạy cảm nhưng cho kết quả khác nhau khi có phi ASCII nhân vật):

ls -dUl -- .* *

Điều này cung cấp lsmột danh sách rõ ràng các tệp (và thư mục) để liệt kê và hủy kích hoạt lssắp xếp ( -Ulà phần mở rộng GNU).

Có một vài cảnh báo, tùy thuộc vào vỏ bạn đang sử dụng.

  • Với zsh, nomatchtùy chọn mặc định sẽ khiến lệnh bị lỗi nếu thư mục không chứa cả các tệp bị ẩn và không bị ẩn; bạn có thể vô hiệu hóa nomatchđể tránh điều đó, nhưng tốt hơn là nên làm set -o cshnullglobthay vào đó (và lệnh chỉ thất bại nếu không có bất kỳ khối nào khớp với nhau như trong (t)cshcác vỏ Unix đầu tiên).
  • Với zsh, pdkshvà phái sinh của nó và fish, .*sự mở rộng của nó không bao gồm ..., do đó, điều này phù hợp ls -Al. Với các vỏ khác ...được bao gồm để nó phù hợp ls -al. Trong trường hợp sau, bạn cần thay đổi các mẫu hình cầu để loại trừ ...( ls -dUl -- ..?* .[!.]* *).
  • Ngoại trừ fish, (t)cshhoặc zsh, nếu bất kỳ mẫu hình cầu nào không khớp với bất cứ thứ gì, lssẽ tạo ra một thông báo lỗi; bạn có thể tránh điều này bằng cách đặt nullglobtùy chọn (trong bashhoặc zshít nhất) hoặc bằng cách chuyển hướng stderrđến /dev/null( ls -dUl -- ..?* .[!.]* * 2>/dev/null). Nếu bạn sử dụng nullglob, hãy coi chừng hành vi có khả năng gây ngạc nhiên (xem Shell ăn các ký tự `?` ). fishcư xử như bashvới nomatchngoại trừ việc khi tương tác, một thông điệp cảnh báo sẽ được phát hành cho mỗi glob mà không có trận đấu.

(Cảm ơn Stéphane Chazelas vì tất cả các phản hồi!)


Lưu ý rằng không phải tất cả các shell sẽ sắp xếp danh sách bằng thứ tự đối chiếu của miền địa phương. mkshdashví dụ sẽ không sắp xếp trường hợp không nhạy cảm.
Stéphane Chazelas

1
Lưu ý rằng -U(có nghĩa là chưa được sắp xếp) là một phần mở rộng GNU. Một số lstriển khai khác như FreeBSD có -Unhưng nó không dành cho danh sách chưa được sắp xếp.
Stéphane Chazelas

Với GNU ls, bạn cần --trước khi .*triển khai chấp nhận các tùy chọn sau các đối số (trừ khi POSIXLY_CORRECT ở trong môi trường)
Stéphane Chazelas

Lén lút (+1)! Tuy nhiên, tôi không chắc chắn làm thế nào tôi sử dụng nó dễ dàng trong mọi trường hợp, tức là trong bí danh hoặc chức năng. Ví dụ, nó sẽ phải thay đổi nếu tôi muốn chỉ định một thư mục cụ thể lslàm đối số.
Sparhawk

1
@PeterCordes [!.]là chính xác. Xem pubs.opengroup.org/onlinepub/9699919799/utilities/ ,. Một số shell (hầu hết?) Cho phép ^như một từ đồng nghĩa !trong các khối nhân vật bị phủ định. Trong mọi trường hợp, tôi thích .[!.] .??* *dễ hiểu hơn một chút so với.[!.]* ..?* *
jrw32982 hỗ trợ Monica

4

Bạn có thể chỉ cần sử dụng hai lslệnh riêng biệt :

$ ls -dl ..?* .[^.]* 2>/dev/null ; ls -dl *
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 .a
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 .b
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 a
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 A
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 b
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 B
-rw-r--r--. 1 sparhawk sparhawk 0  8 Jun  09:29 你好嗎

Không giống như các câu trả lời khác cho đến nay, cách tiếp cận này hiển thị các tệp chấm trước tiên tránh các mục ...mục, sau đó các mục còn lại ls theo thứ tự bảng chữ cái.

@StephenKitt câu trả lời có thể được cải thiện mặc dù để đạt được kết quả tương tự:

$ ls -dUl ..?* .[^.]* * 2>/dev/null

+1 cũng vậy, nhưng theo câu trả lời của StephenKitt, tôi không chắc mình sẽ sử dụng nó dễ dàng như thế nào trong mọi trường hợp, tức là trong bí danh hoặc chức năng. Ví dụ, nó sẽ phải thay đổi nếu tôi muốn chỉ định một thư mục cụ thể lslàm đối số. (FWIW Tôi đang sử dụng zsh, nhưng điều này hữu ích cho người bash, tôi cho là vậy.)
Sparhawk

-2

Bạn có thể chơi với các tùy chọn lệnh ls . Thử đi:

# ls -laXr

Ở đâu:

-l     use a long listing format
-a, --all
              do not ignore entries starting with .
-X     sort alphabetically by entry extension
-r, --reverse
              reverse order while sorting

Xin lỗi, điều đó dường như không làm những gì tôi muốn. Các -Xlá cờ sắp xếp bởi phần mở rộng sau khi ., đó là hoàn toàn khác nhau. Ngoài ra, các tập tin theo thứ tự bảng chữ cái ngược. Ngoài ra, trong khi các dotfiles là ví dụ đầu tiên của tôi, nó sẽ không hoạt động trong mọi trường hợp (ví dụ a.b c.d .a .c). Ngoài ra, bạn đã sử dụng -athay vì -A.
Sparhawk
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.