Как сделать, чтобы глобальные классы символов bash учитывали регистр символов?

571
Mutant Bob

Я создал несколько таких файлов, как knob_A.pngи knob_a.pngмой товарищ по команде в Windows сказал, что это вызвало проблемы с ее приложением. Я решил назвать это knob_W.pngвместо knob_a.png. Затем я сделал rsync до нашего общего сервера. Для того, чтобы навести порядок, я тогда сделал

rm knob_[a-d]*.png 

и это knob_A.pngтоже убрано . Это неправильно как футбольная бита.

Ни то, shopt -s nocaseglobни другое не shopt -u nocaseglobведет себя так, как я хочу.

Как мне сказать bash, чтобы его глобусы были чувствительны к регистру, как в старые времена?

4

2 ответа на вопрос

7
xordspar0

Bash чувствителен к регистру. Проблема заключается в порядке сортировки символов в диапазоне. Из руководства Bash ( info bash):

Порядок сортировки символов в выражениях диапазона определяется текущей локалью и значением переменной оболочки «LC_COLLATE», если она установлена.

Например, в языковом стандарте C по умолчанию «[a-dx-z]» эквивалентно «[abcdxyz]». Многие локали сортируют символы в порядке словаря, и в этих локалях «[a-dx-z]» обычно не эквивалентно «[abcdxyz]»; например, это может быть эквивалентно '[aBbCcDdxXyYz]'. Чтобы получить традиционную интерпретацию диапазонов в выражениях в скобках, вы можете принудительно использовать локаль C, установив для переменной окружения 'LC_COLLATE' или 'LC_ALL' значение 'C'.

Попробуй сделать

export LC_COLLATE=C 
Вы можете расширить пример оболочки до: `LC_COLLATE = C; ls knob_ [ad] *. png`. Я привык делать такие вещи, как `LC_COLLATE = C ls knob_ [ad] *. Png`, который не работает, возможно потому, что он только устанавливает среду подпроцесса и не влияет на bash, который оценивал глобус. Mutant Bob 6 лет назад 1
@MutantBob является правильным: bash расширяет глобус до того, как он устанавливает LC_COLLATE, но основная проблема заключается в том, что простой X = Y устанавливает локальную переменную оболочки X, которая _только_ не то же самое, что переменная среды, а LC_COLLATE - переменная среды. Denis Howe 5 лет назад 1
Чтобы временно установить переменную среды для одной команды, скажите: `LC_COLLATE = C command` Примечание: _no точка с запятой_ между назначением и командой. Чтобы установить его до конца сеанса, скажите: `export LC_COLLATE = C` Это повлияет на глобусы в последующих строках. Denis Howe 5 лет назад 0
1
DonnieDarko

Bash имеет опцию оболочки для сохранения соответствия шаблону, поэтому регистр не игнорируется во время расширения. Вы можете добавить shopt -s globasciirangesв свой скрипт, чтобы включить регистрозависимые совпадения, и отключить его с помощью shopt -u globasciiranges. См. Bash Reference - Shopt Builtin

В качестве альтернативы вы можете использовать, LC_COLLATE=Cкак указано в другом ответе, но убедитесь, что он был экспортирован в вашу среду сexport LC_COLLATE