Độ nhạy trường hợp trong hình vuông khung


10

Thông thường, bash globalbing là trường hợp nhạy cảm:

$ echo c*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo C*
CarePackage.md ChocRippleCake.md Clips

Sử dụng dấu ngoặc vuông dường như không thay đổi điều này:

$ echo [c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C]*
CarePackage.md ChocRippleCake.md Clips

Nó vẫn không thay đổi nếu sử dụng dấu gạch nối:

$ echo [c-c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C-C]*
CarePackage.md ChocRippleCake.md Clips

Nhưng các chữ cái được xen kẽ:

$ echo [B-C]*
CarePackage.md casefix.pike cdless chalices.py charconv.py chocolate.pike ChocRippleCake.md circum.py clip.pike Clips cpustats.pike crop.pike cwk2txt.py
$ echo [b-c]*
beehive-anthem.txt bluray2mkv.pike branch branchcleanup.pike burdayim.pike casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py

Điều này cho thấy dấu gạch nối đang sử dụng thứ tự miền địa phương, "AaBbCcDd". Vậy: có cách nào để toàn cầu hóa cho tất cả các tệp bắt đầu bằng chữ in hoa không?


3
Ngoài ra, hãy lưu ý gotcha rằng [AZ] khớp với mọi chữ cái viết thường ngoại trừ 'z'!
PJTraill

Câu trả lời:


12

Trong bash phiên bản 4.3 trở lên, có một tùy chọn shopt được gọi là globasciiranges:

Theo shopt buildin gnu man page :

globalasciiranges
Nếu được đặt, các biểu thức phạm vi được sử dụng trong các biểu thức khung khớp mẫu (xem Khớp mẫu) hoạt động như trong ngôn ngữ C truyền thống khi thực hiện so sánh. Đó là, trình tự đối chiếu của miền địa phương hiện tại không được tính đến, vì vậy 'b' sẽ không đối chiếu giữa 'A' và 'B', và các ký tự ASCII chữ hoa và chữ thường sẽ đối chiếu với nhau.

Kết quả là bạn có thể

$ shopt -s globasciiranges 
$ echo [A-Z]*

Sử dụng shopt -uđể vô hiệu hóa.

Một cách khác là thay đổi ngôn ngữ thành C. Bạn có thể tạm thời thực hiện việc này bằng cách sử dụng một mạng con:

$ ( LC_ALL=C ; printf '%s\n' [A-Z]*; )

Bạn sẽ nhận được kết quả bạn cần và khi lớp vỏ phụ kết thúc, miền địa phương của lớp vỏ chính của bạn vẫn không thay đổi so với trước đây.

Một cách khác là thay vì [A-Z]sử dụng mở rộng cú đúp {A..Z}cùng với nullglobtùy chọn bash shopt.

Bằng cách kích hoạt nullglobtùy chọn, nếu một mẫu không được khớp trong quá trình mở rộng tên đường dẫn, một chuỗi null được trả về thay vì chính mẫu đó.
Kết quả là cái này sẽ hoạt động như mong đợi:

$ shopt -s nullglob;printf '%s\n' {A..Z}*

2
Hoàn hảo, cảm ơn. Tôi không thể sử dụng [[:upper:]]vì tôi thực sự muốn chỉ là một phần của bảng chữ cái, nhưng điều này hoạt động.
rosuav

1
@rosuav Chào mừng. Kiểm tra cũng thay thế vỏ phụ.
George Vasiliou

Nếu được kích hoạt tương đương với ngôn ngữ C - bạn có nghĩa là nó ảnh hưởng đến miền địa phương được sử dụng cho toàn cầu và không có gì khác? (Một liên kết tham chiếu sẽ rất hữu ích - thứ tốt nhất tôi có thể tìm thấy là gnu.org/software/bash/manual/html_node/Potype-Matching.html , nhưng tôi sẽ thích một danh sách tất cả các tùy chọn shell, nhưng thiếu Gloasciiranges từ gnu.org/software/bash/manual/html_node/ , cũng là câu hỏi unix.stackexchange.com/questions/227070/ Lỗi xử lý vấn đề này rộng rãi.) Cũng từ phiên bản 4.3.
PJTraill

@PjTrail Xem chỉnh sửa của tôi với một liên kết tham chiếu đến tất cả các tùy chọn shopt. Ngoài ra, bạn có thể chạy man bashtrong thiết bị đầu cuối của bạn và tìm kiếm (sử dụng /) cho globalasciiranges.
George Vasiliou

Sẽ không LC_ALL=C printf '%s\n' [A-Z]*làm việc cho giải pháp thứ hai của bạn - mà không có một mạng con? BTW: có một lỗi đánh máy: nullblognhưng nó quá ít ký tự để tôi sửa nó.
Joe

5

Bạn có thể viết tất cả các chữ cái viết hoa tốt như:

[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*

hoặc sử dụng có thể sử dụng lớp ký tự được đặt tên [:upper:]để thể hiện tất cả các chữ cái in hoa trong hiện tại của bạn locale:

[[:upper:]]*

Như bạn đã nhận thấy, trong khi sử dụng phạm vi như [B-C]chữ hoa và chữ thường cho cùng một ký tự chữ cái đang được sắp xếp một cách ngẫu nhiên (theo thứ tự đối chiếu của locale).


3

Bao gồm các ký tự khác không trực quan trong các phạm vi ký tự, chẳng hạn như bao gồm các chữ cái viết thường trong một phạm vi có ranh giới là các chữ cái viết hoa, là do LC_COLLATEcài đặt ngôn ngữ. LC_COLLATEđược cho là chỉ ra thứ tự sắp xếp, nhưng nó thực hiện công việc kém của nó (sắp xếp các chuỗi phức tạp hơn những gì địa phương có thể làm) và bạn tốt hơn nếu không có nó. Tôi khuyên bạn nên xóa LC_COLLATEkhỏi cài đặt ngôn ngữ của bạn. Nếu bạn thiết lập đang LANG, hoặc LANGUAGE, không làm điều đó và thiết lập chỉ là những người bạn cần: LC_CTYPE, LC_MESSAGES, LC_TIME.

Để biết thêm thông tin về địa phương, hãy xem Tôi nên đặt ngôn ngữ của mình ở đâu và ý nghĩa của việc làm này là gì? đặt LC_ * nhưng không LC_ALL

Để có kết quả đáng tin cậy trong tập lệnh bất kể cài đặt của người dùng, hãy đặt LC_ALL=C.


0

Bộ:

shopt -u nocaseglob

Từ trang bash man:

>     nocaseglob
>         If  set,  bash matches filenames in a case-insensitive
>         fashion when performing pathname expansion (see Pathname
>          Expansion above).

Nếu bạn đặt 'continasciiranges', tôi không biết điều gì sẽ xảy ra với các nhân vật không phải là ascii như utf-8


0

echo [cC] * nên làm những gì bạn muốn, tương tự [A-Za-z] *

Tôi ở đây vì toàn cầu hóa trên hệ thống của tôi đã ngừng phân biệt chữ hoa chữ thường, do đó, rất nhiều tập lệnh của tôi không còn hoạt động như bình thường :-(


Điều đó trái ngược với những gì tôi đang thấy. Nhưng kiểm tra các câu trả lời khác cho lời đề nghị.
rosuav
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.