Чутливість корпусу в глобусі квадратної дужки


10

Зазвичай, глобус-башшон чутливий до регістру:

$ 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

Використання квадратних дужок, схоже, це не змінить:

$ 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

Він все ще не змінює його, якщо використовується дефіс:

$ 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

Але букви перемежовуються:

$ 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

Це говорить про те, що дефіс використовує локальний порядок "AaBbCcDd". Отже: чи є спосіб глобалізувати всі файли, які починаються з великої літери?


3
Також зверніть увагу на gotcha, що [AZ] відповідає кожній малої літери, окрім "z"!
PJTraill

Відповіді:


12

У bash версії 4.3 та пізнішої версії є опція shop globasciiranges:

За покупованими вбудованими сторінками gnu man :

globasciiranges
Якщо встановлено, вирази діапазону, які використовуються у виразних дужках вирівнювань за малюнком (див. Зрівняння шаблонів), поводяться як у традиційній мові С під час порівняння. Тобто, послідовність згортання поточної локальної локації не враховується, тому "b" не порівнюватиметься між "A" та "B", а символи ASCII верхнього та нижнього регістру будуть узгоджені разом.

В результаті ви можете

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

Використовувати shopt -uдля відключення.

Ще один спосіб - це змінити локаль на C. Ви можете це зробити тимчасово, використовуючи нижню частину оболонки:

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

Ви отримаєте необхідні результати, і коли допоміжна оболонка буде закінчена, локальний режим вашої основної оболонки залишається незмінним до того, що було раніше.

Ще одна альтернатива - замість того, [A-Z]щоб використовувати розширення дужок {A..Z}разом з nullglobопцією bash shopt.

Увімкнувши nullglobопцію, якщо шаблон не збігається під час розширення імені шляху, повертається нульовий рядок замість самого шаблону.
Як результат, цей буде працювати, як очікувалося:

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

2
Ідеально, дякую. Я не можу використовувати, [[:upper:]]тому що я дійсно хочу лише частину алфавіту, але це працює.
rosuav

1
@rosuav Ласкаво просимо. Перевірте також альтернативу додаткової оболонки.
Джордж Васильоу

"Якщо увімкнено дорівнює локальній мові C" - ви маєте на увазі, що це впливає на локаль, що використовується для глобалізації, і ні на що інше? (Посилання на посилання було б корисним - найкраще, що я можу знайти, - це gnu.org/software/bash/manual/html_node/Pattern-Matching.html , але я вважав за краще список усіх параметрів оболонки, але глобальних діапазонів немає від gnu.org/software/bash/manual/html_node/… ; також питання unix.stackexchange.com/questions/227070/… обробляє це питання широко.) Також з версії 4.3.
PJTraill

@PjTrail Перегляньте мою редагування з посиланням на всі знімаються параметри. Також ви можете запустити man bashу свій термінал і шукати (використовуючи /) глобальні діапазони.
Джордж Васильоу

Не вдалося б LC_ALL=C printf '%s\n' [A-Z]*працювати за вашим другим рішенням - без передплати? BTW: є помилка помилки:, nullblogале мені замало символів, щоб виправити це.
Джо

5

Ви можете написати всі великі літери просто так:

[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*

або можете використовувати названий клас символів [:upper:]для представлення всіх великих літер у поточному locale:

[[:upper:]]*

Як ви помітили, під час використання діапазону, як [B-C]верхній і нижній регістр для одного й того ж алфавітного символу, розташовуються поряд (відповідно до порядку зіставлення locale).


3

Включення "неінтуїтивних" символів у діапазони символів, такі як включення малих літер у діапазон, межі якого є великими літерами, обумовлено LC_COLLATEналаштуванням мови. LC_COLLATEповинен вказувати порядок сортування, але це робить погану роботу (сортування рядків складніше, ніж те, що можуть робити локалі), і вам краще без цього. Рекомендую видалити LC_COLLATEз налаштувань локальної мови. Якщо ви встановлюєте LANG, або LANGUAGE, не роблять цього і встановити тільки ті , що вам потрібно: LC_CTYPE, LC_MESSAGES, LC_TIME.

Щоб отримати докладнішу інформацію про локалі, див. Що потрібно встановити для своєї мови та які наслідки це робити? і встановіть LC_ *, але не LC_ALL

Щоб отримати надійні результати в сценарії незалежно від налаштувань користувача, встановіть LC_ALL=C.


0

Набір:

shopt -u nocaseglob

З сторінки bash man:

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

Якщо ви встановите "globasciiranges", я не знаю, що буде з персонажами, які не входять в асоцію, як utf-8


0

echo [cC] * має робити те, що ти хочеш, аналогічно [A-Za-z] *

Я тут, тому що глобалізація в моїй системі просто перестала бути чутливою до регістру, тому навантаження моїх сценаріїв більше не працюють як слід :-(


Це протилежне тому, що я бачу. Але перевірте інші відповіді щодо пропозицій.
rosuav
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.