Используя TR управляют с диапазонами символов

В течение прошлых нескольких месяцев я узнавал о командной строке с помощью William E. Shotts Командную строку Linux. Командная строка Linux остается популярной книгой для новичков, которые хотели бы узнать больше о командной строке Linux.

В одной из глав это представляет tr команда. В книге говорится, что наборы символов могут быть созданы одним из трех способов: перечислимый список такой как ABCDEFGHIJKLMNOPQRSTUVWXYZ; диапазон символов, такой как A-Z; и классы символов POSIX, такой как [:upper:].

Часть, которую я не понимаю, - когда книга говорит читателю быть осторожным об использовании диапазонов символов для набора символов из-за порядка сопоставления локали и предлагает, чтобы читатель использовал классы символов POSIX вместо этого.

Я лично никогда не встречался с проблемой с помощью диапазонов символов такой как A-Z с

echo "lowercase letters" | tr a-z A-Z

итак, почему я должен воздержаться от использования диапазонов символов в пользу классов символов POSIX?

В случае, если Вы задаетесь вопросом, моя локаль является en_US.UTF-8.

1
задан 9 November 2017 в 04:55

1 ответ

Вы используете UTF-8. Yay! ASCII и следовательно UTF-8 (потому что парни UTF пытались сделать это надмножеством ASCII), имеют алфавиты в алфавитном порядке без разрывов, таким образом, a-z содержит все нормальные символы нижнего регистра и ничто иное, и так далее.

Однако это не должно быть верно на некотором другом кодировании. Классическим примером является EBCDIC:

Разрывы между буквами сделали простой код, который работал в сбое ASCII над EBCDIC. Например, for (c='A';c<='Z';++c) установил бы c к 26 буквам в алфавите ASCII, но 40 символам включая многие неназначенные в EBCDIC. Фиксация этого необходимого усложнения кода с вызовами функции, которому значительно сопротивлялись программисты.

Я хотел бы думать, что никто не использует странный материал как это еще, но кто знает?


TR GNU не поддерживает Unicode, AFAIK, но для программ, которые делают, [[:upper:]] также соответствовал бы символам Unicode, которые считают алфавитами верхнего регистра, например, полноширинным "A", или с диакритическим знаком: À.

$ printf "%s\n" A a A À | grep '[[:upper:]]'
A
A
À
$ printf "%s\n" A a A À | grep '[A-Z]'   # I'm also using Unicode, so grep tries to be friendly
A
À
$ printf "%s\n" A a A À | LC_ALL=C grep '[A-Z]'
A 
1
ответ дан 7 December 2019 в 15:27

Другие вопросы по тегам:

Похожие вопросы: