Обычно, bash globbing чувствителен к регистру:
$ 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". Итак: есть ли способ для glob для всех файлов, которые начинаются с заглавной буквы?
[A-Z]
совпадают строчные буквы в bash?Ответы:
В bash версии 4.3 и более поздних версиях существует опция покупки
globasciiranges
:По словам собравшихся встроенных гну man-страниц :
В результате вы можете
Используйте
shopt -u
для отключения.Другой способ - изменить локаль на C. Вы можете сделать это временно, используя подоболочку:
Вы получите нужные вам результаты, и когда суб-оболочка будет завершена, локаль вашей основной оболочки останется неизменной, какой была раньше.
Другой вариант - вместо
[A-Z]
использования расширения скобок{A..Z}
вместе сnullglob
опцией bash shopt.При включении этой
nullglob
опции, если шаблон не сопоставляется во время раскрытия имени пути, вместо самого шаблона возвращается пустая строка.В результате этот будет работать как ожидалось:
источник
[[:upper:]]
потому что я на самом деле хочу только часть алфавита, но это работает.man bash
в своем терминале и искать (используя/
) globasciiranges.LC_ALL=C printf '%s\n' [A-Z]*
ваше второе решение - без подоболочки? КСТАТИ: есть опечаткаnullblog
, но я слишком мало символов, чтобы исправить это.Вы можете написать все заглавные буквы просто так:
or use может использовать именованный класс символов
[:upper:]
для представления всех заглавных букв в вашем текущемlocale
:Как вы заметили, при использовании диапазона, например,
[B-C]
верхний и нижний регистры для одного и того же буквенного символа располагаются рядом (в соответствии с порядком сортировкиlocale
).источник
Включение «неинтуитивных» символов в диапазоны символов, например включение строчных букв в диапазон, границы которого являются заглавными буквами, обусловлено
LC_COLLATE
настройкой локали.LC_COLLATE
должен указывать порядок сортировки, но он плохо справляется с этим (сортировка строк более сложна, чем то, что может сделать локаль), и вам лучше без него. Я рекомендую удалитьLC_COLLATE
из ваших региональных настроек. Если вы устанавливаетеLANG
, илиLANGUAGE
, не делают этого и установить только те , что вам нужно:LC_CTYPE
,LC_MESSAGES
,LC_TIME
.Для получения дополнительной информации о региональных настройках см. Раздел « Что я должен установить для своей региональной настройки» и каковы последствия этого? и установите LC_ *, но не LC_ALL
Чтобы получить достоверные результаты в скрипте независимо от настроек пользователя, установите
LC_ALL=C
.источник
Установлен:
Со страницы руководства bash:
Если вы установите 'globasciiranges', я не знаю, что будет с не-ascii символами, такими как utf-8
источник
echo [cC] * должен делать то, что вы хотите, аналогично [A-Za-z] *
Я здесь, потому что глобализация в моей системе перестала быть чувствительной к регистру, поэтому загрузка моих скриптов больше не работает так, как должна :-(
источник