Як конвертувати файли UTF-8 txt у всі великі регістри в bash?


10

У мене є кілька файлів UTF-8 .txt, які я хотів би перетворити на всі великі регістри. Якби це був просто ASCII, я міг би використовувати:

tr [:lower:] [:upper:]

Але оскільки я працюю з діакритикою та іншим, це, здається, не працює. Я думаю, це може спрацювати, якщо я встановлю відповідну локаль, але мені потрібен цей сценарій, щоб він був переносним.

Відповіді:


14

Всі з:

tr '[:lower:]' '[:upper:]'

(Не забудьте лапки, в іншому випадку , що не працюватиме , якщо є файл з ім'ям :, l... або rв поточному каталозі) або:

awk '{print toupper($0)}'

або:

dd conv=ucase

призначені для перетворення символів у великі регістри відповідно до правил, визначених у поточному локалі. Однак навіть там, де локали використовують UTF-8 як набір символів і чітко визначають перетворення з малих літер у великі регістри, принаймні GNU dd, GNU trі mawk(наприклад, за замовчуванням awkдля Ubuntu) не слідкують за ними. Крім того, немає стандартного способу вказувати локалі, окрім Cабо POSIX, тому, якщо ви хочете перетворити файли UTF-8 у великі регістри портативно, незалежно від поточної мови, вам не пощастить зі стандартною панеллю інструментів.

Як часто для портативності найкраща ставка:

$ echo lľsšcčtťzž | PERLIO=:utf8 perl -pe '$_=uc'
LĽSŠCČTŤZŽ

Тепер вам слід остерігатися, що не всі згодні з тим, що являє собою велику версію конкретного символу.

Наприклад, у турецьких мовах великі літери iне I, але İ( <U0130>). Ось із інструментальним інструментом heirloom trзамість GNU tr:

$ echo ií | LC_ALL=C.UTF-8 tr '[:lower:]' '[:upper:]'
IÍ
$ echo ií | LC_ALL=tr_TR.UTF-8 tr '[:lower:]' '[:upper:]'
İÍ

На моїй системі, perlперетворення до верхнього визначаються /usr/share/perl/5.14/unicore/To/Upper.pl, і я вважаю , що він веде себе по- різному на кілька персонажів з LIBC GNU toupper()в C.UTF8локалі, наприклад, perlбути більш точними. Наприклад, perlправильно перетворює ɀ в Ɀ , GNU libc (2.17) не робить.


Наскільки це варте, я працюю з чеськими літерами (а приклад, який ви використовували, насправді є словацькою), де всі великі літери чітко визначені, але набір локалів, ймовірно, буде C, а не чеським, тому це проблема. Perl вже використовується в цій ланцюжку інструментів, тому додавання іншого використання може бути не надто поганим. Дякую за детальне пояснення, btw!
VPeric

3

Я думаю, ви можете це зробити awkі з його toupperфункцією.

Наприклад

Не працює з GNU tr:

$ echo lľsšcčtťzž | tr '[:lower:]' '[:upper:]'
LľSšCčTťZž

Працює з GNU awk:

$ echo lľsšcčtťzž | awk '{ print toupper($0) }'
LĽSŠCČTŤZŽ

@StephaneChazelas - дякую, що я змінив невдалий приклад.
slm

Це залежить від поточного місцеположення та від trабо awkреалізації. Наприклад, більшість trбуде правильно перетворювати символи, коли в локалі UTF8, відповідно до поточної локалі, GNU trне робить. mawkне робить.
Стефан Шазелас

1
Насправді, у FreeBSD (9.1) все навпаки. Це працює з tr, але не зawk
Стефан Шазелас

@StephaneChazelas - я не настільки розбираюся в варіаціях 8-). Хтось просто зголосився, цікаво, чому?
slm

2

Це працює з ОС X, trале не з GNU tr:

tr '[:lower:]' '[:upper:]'

Це працює з, gawkале не з mawkабо nawk(що є /usr/bin/awkв OS X):

awk '{print toupper($0)}'

Ще один варіант - використовувати GNU sed:

sed 's/./\u&/g'

У Bash 4.0 та пізніших версіях ви також можете використовувати ^^розширення параметрів:

while IFS= read -r l;do printf %s\\n "${l^^}";done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.