#pragma css /css/2018.css <<BI>> = Комментарии к практикуму 8 = == Кодировка файлов скриптов == === Узнать кодировку файла === Проверить кодировку файла можно с помощью команды `file`. Главная функция этой команды -- угадать тип файла по его содержимому, но она умеет определять и основные типы кодировок. Чтобы показать, в том числе, кодировку, есть опция `-i`, чтобы показать только кодировку тоже есть опция (`--mime-encoding`), но её сложнее набирать. В случае кодировки UTF-8 будет написано "charset=utf-8", или "charset=us-ascii", если в вашем файле только символы из первой половины кодовой таблицы ASCII (т.е., только цифры, английские буквы, простые знаки препинания, пробельные символы и еще кое-что, более менее все, что можно найти на клавиатуре в английской раскладке), которые в UTF-8 кодируются так же, как в ASCII. В случае, CP1251 (она же Windows-1251 и ANSI по версии Far, стандартная 8-битная кодировка для русского языка в Windows), CP866 (устаревшая 8-битная кодировка для русского языка в Windows), KOI8-R (устаревшая 8-битная кодировка для русского языка в Unix-подобных операционных системах) будет напечатано "charset=iso-8859-1" (`file` не умеет различать почти никакие 8-битные ASCII-совместимые кодировки). Если вам вдруг все-таки надо точно определить кодировку файла, можете использовать команду `chardet`. === Как поменять кодировку файла === Для изменения кодировки текстовых файлов существует команда `iconv`. Стандартный способ запуска следующий: {{{#!highlight bash iconv -f FROM -t TO OLD_FILE | less # чтобы убедиться, что смена кодировки происходит удачно iconv -f FROM -t TO OLD_FILE > NEW_FILE # чтобы сохранить перекодированный текст в файл NEW_FILE }}} `FROM` и `TO` -- названия кодировок, которые понимает `iconv`, а OLD_FILE и NEW_FILE -- имена файлов. Полный список всех поддерживаемых названий кодировок можно узнать с помощью опции `-l`: {{{#!highlight bash iconv -l | less # список длинный! }}} В вашем случае команда почти наверняка будет следующая: {{{#!highlight bash iconv -f cp1251 -t utf8 OLD_FILE > NEW_FILE }}} === Проблемы с UTF-8 (BOM) === С кодировкой UTF-8 есть некоторая подстава, про которую я каждый раз забываю рассказать. Эта кодировка допускает в самом начале файла присутствие так называемого BOM (byte order mark) -- специального символа Unicode, который в случае UTF-8 кодируется тремя байтами 0xEF 0xBB 0xBF. BOM не является обязательным или даже рекомендуемым для UTF-8, но некоторые программы его добавляют при сохранении файла в кодировке UTF-8. Например, Far поступает именно так, и не только Far. Все программы, которые умеют понимать UTF-8, обычно правильно обрабатывают этот символ и просто игнорируют его при отображении текста. Но с шебангом (#!) начинаются проблемы. Как я вам говорил, символы #! должны быть в самом начале файла, иначе они не работают, в том числе, если перед ними стоит BOM, который ещё и не отображается в текстовом редакторе. Выход простой -- удалить BOM. Но проще сказать, чем сделать. Для начала надо убедиться, что он действительно есть. Самый простой способ -- посмотреть файл в `less`. Если в начале файла есть BOM, то он будет отображаться в виде <U+FEFF> в начале первой строки. Теперь вам надо удалить первый символ или 3 первых байта (в этом случае). Это можно сделать кучей разных способов. Например, с помощью sed: {{{#!highlight bash sed -Ei '1s/^.//' FILE # -i для изменения файла "на месте", используйте с осторожностью! # 1 - адрес первой строки # s/^.// - удаление любого первого символа в строке }}} На самом деле, в случае скриптов, начинающихся с #!, можно использовать следующую команду, независимо от того, был в начале BOM, или нет: {{{#!highlight bash sed -Ei '1s/^[^#]*#/#/' FILE # -i для изменения файла "на месте", используйте с осторожностью! # 1 - адрес первой строки # s/^[^#]*#/#/ - удаление любого количества любых символов до первого символа # }}} == Кодировка переносов строк == Существует всего два распространенных способа кодировать переносы строк в текстовых файлах: стиль Windows и стиль Unix. Как не сложно догадаться, почти все программы в Linux ожидают переносы строк в стиле Unix. В Windows переносы строк кодируются двумя символами CR (возврат каретки) и LF (перевод строки). В Unix -- одним символом LF. Самый простой способ привести файл к Unix формату -- просто удалить из него всего символы CR вообще, если они есть. Для этого можно использовать команду `tr -d`. {{{#!highlight bash cat OLD_FILE | tr -d "\r" > NEW_FILE # \r распространенное обозначение CR, \n -- LF, \t -- TAB # OLD_FILE и NEW_FILE должны быть разными файлами! Иначе потеряете все содержимое. # или tr -d "\r" < OLD_FILE > NEW_FILE }}} Проверить наличие CR в файле можно с помощью: {{{#!highlight bash less -U FILE # отображает CR как ^M и TAB на ^I cat -A FILE | less # cat -A меняет CR на ^M, LF на $ и TAB на ^I }}}