AWK не захватывает Z, используя диапазон регулярных выражений [0-z]

63
7

Используя gensub в awk, я заметил, что мой капитал Z не распознается с использованием следующей строки awk:

awk '{name=gensub(/[0-z]/,"succes","g",$0); print name}' range2.txt

В файле "range2.txt", имеющем следующий текст:

A
B
Z

На Z он просто возвращает Z вместо "succes". Он вернет цель, если не будет. Но почему это не имеет себе равных? Это мешало мне ходить в цикле, когда я смешивал свою проблему с какой-то другой. У меня есть решение, чтобы выполнить проделанную работу, но мне все еще интересно, почему. Я пробовал все другие буквы альфабетов и цифры, которые все возвращают успех, кроме капитала Z. Однако это письмо находится в большей или меньшей степени в середине диапазона.

Локальный charmap возвратил ISO-8859-15, который имеет Z в середине диапазона 0-z.

Я рассмотрел вопрос о том, что я только что написал, но не вижу больше открытий. Я также использовал другие строковые функции AWK, но ни один из них не нашел Z. ie SPLIT MATCH GSUB.

Я попытался просто добавить Z вручную, а затем он работает:

print name} 'range2.txt

Но все равно...

спросил(а) 2021-01-25T17:34:11+03:00 4 месяца, 2 недели назад
1
Решение
63

Единственный возможный ответ заключается в том, что Z не находится внутри указанного диапазона в локали. Ваш язык может быть разбит на вашем дистрибутиве. Попробуйте другие инструменты, такие как grep и sed, с тем же диапазоном, чтобы увидеть, можете ли вы воспроизвести проблему - если это проблема с вашей локалью, если она не с вашим awk.

ответил(а) 2021-01-25T17:34:11+03:00 4 месяца, 2 недели назад
45

После каждого ввода я могу ответить на этот вопрос сам.

LC_all = C IS действительно работает, но он должен быть экспортирован как переменная среды. Таким образом, export LC_ALL=C (или, более конкретно, LC_COLLATE) - это то, что я должен был выдать на консоли, а не только LC_ALL=C Последний может использоваться, но только после этого команда должна быть независимой от локали.

Awk должен быть независимым от локали с версии 4, но моя версия - еще 3. Поэтому для меня мне все равно придется выдавать awk:

LC_ALL=C awk '{name=gensub(/[0-z]/,"succes","g",$0); print name}' range2.txt

или

LC_COLLATE=C awk '{name=gensub(/[0-z]/,"succes","g",$0); print name}' range2.txt

Мой grep использует другой язык. Я не могу найти, где эти локали установлены, что было бы интересно, но я вижу разные поведения в отношении диапазонов символов. Также grep может извлечь выгоду из того, что он не зависит от локали. Итак, где в моей настройке:

echo Z | grep [0-z]

ничего не возвращает, следующее возвращает Z

LC_ALL echo Z | grep [0-z]

ответил(а) 2021-01-25T17:34:11+03:00 4 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема