01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: | #!/bin/bash # Программа перекодировки текста ср1251 в КОИ-8 # Функция построения таблицы перекодировки function winkoi { # Подстановка номеров букв koi8=${num[cp1251]} num=(01 02 27 07 04 05 26 32 11 12 13 14 15 16 17 20 \ 22 23 24 25 06 10 03 36 33 35 37 31 30 34 00 21) # Конкатенация кодов для строчных и заглавных букв в koi8 for i in ${num[*]} do # перечисление номеров букв low=$low"\3$i" # склеить lower koi octal code set up=$up"\3`expr $i + 40`" # склеить upper koi octal code set done echo $up$low # total koi octal code set return # возврат из функции winkoi } # Диагностика аргументов командной строки # Контроль числа аргументов if test $# -lt 2 then echo "Usage: `basename $0` input.win output.koi" exit −7 fi if! test -f $1 # Проверка существования входного файла then echo "$1: No such regular file" >&2 exit 2 # ENOENT fi # Контроль доступа чтения для входного файла if! test -r $1 then echo "$1: Permission denied to read" >&2 exit 13 # EACCES fi # Контроль маршрутного имени для выходного файла curdir=`pwd` # маршрутное имя текущего каталога outdir=`expr $2: '\(.*/\)' \| $curdir` # Контроль каталога по (пере)записи if [! -w $outdir -a! -e $2 ] then echo "$outdir: Permission denied to write" >&2 exit -13 fi # Проверка, что выходной файл не каталог if test -d $2 then echo "$2: Is directory" >&2 exit 21 # EISDIR fi # Контроль перезаписи выходного файла if [ -e $2 -a! -w $2 ] then echo $2: Permission denied to rewrite exit 13 # EACCES fi # Транслитерация кодов cp1251 в koi8 cat $1 | tr "\300-\337\340-\377" `winkoi` > $2 exit 0 # Нормальное завершение программы |
Для интерпретации программы, записанной в файле rnn.sh, командным процессором BASH нужно ввести следующую командную строку в графическом окне эмулятора терминала xterm:
$ bash rnn.sh input.win output.koi
Имя файла с исходными данными для перекодировки input.win передается программе первым аргументом. Результатом выполнения этой команды будет создание или перезапись файла output.koi, имя которого указано вторым аргументом. Результат этой перекодировки следует проверить визуально в графическом окне текстового редактора xedit с кириллическим шрифтом КОИ-8.
Строки 20-57 сценарияреализуют многоэтапную проверку аргументов командной строки вызова программы.
Сама процедура перекодировки реализуется в конвейере команд, представленном в строке 60 сценария. Исходный текст из файла input.win, имя которого передано команде конкатенации cat через позиционный параметр $1, направляется на обработку команды транслитерации tr.
Первый параметр команды tr – это строка, состоящая из 64 символов русского алфавита, заданных кодами в восьмеричной системе счисления:
"\300-\337\340-\377"
Если данную строку представить в виде литералов, соответствующих кодировке ср1251 (рис. 1), она будет иметь вид:
"А-Яа-я"
Второй параметр команды tr – тоже строка, состоящая из 64 символов русского алфавита, заданных кодами в восьмеричной системе счисления. Эта строка является результатом выполнения функции winkoi, представленной в строках 05-18 сценария.
Строка формируется на основании матрицы перекодировки num. Каждое значение матрицы представляет собой смещение относительно 0 (начальной позиции таблицы) кода буквы в кодировке КОИ-8 (без учета регистра), дополненное в случае необходимости лидирующими нулями до двух разрядов. Значение смещения представлено в восьмеричной системе счисления и записано в соответствующее той же букве русского алфавита позицию матрицы num.
сp1251 | КОИ-8 | |||||||||||||||||
А | Б | В | Г | Д | Е | Ж | З | ю | а | б | ц | д | е | ф | г | |||
И | Й | К | Л | М | Н | О | П | х | и | й | к | л | м | н | о | |||
Р | С | Т | У | Ф | Х | Ц | Ч | п | я | р | с | т | у | ж | в | |||
Ш | Щ | Ъ | Ы | Ь | Э | Ю | Я | ь | ы | з | ш | э | щ | ч | ъ | |||
а | б | в | г | д | е | ж | з | Ю | А | Б | Ц | Д | Е | Ж | Г | |||
и | й | к | л | м | н | о | п | Х | И | Й | К | Л | М | Н | О | |||
р | с | т | у | ф | х | ц | ч | П | Я | Р | С | Т | У | Ж | В | |||
ш | щ | ъ | ы | ь | э | ю | я | Ь | Ы | З | Ш | Э | Щ | Ч | Ъ |
Рис. 1. Фрагменты кодовых наборов ср1251 и КОИ-8
(буквы русского алфавита)
Так, начальный (нулевой) элемент матрицы перекодировки num [0]соответствует букве А, занимающей начальную позицию в наборе ср1251. Смещение этой буквы в наборе кодов КОИ-8 без учета регистра составляет 18 (num [0]=01). Для следующей за ней буквы Б это смещение составляет 22 (num [1]=02), для В – 278 (num [2]=27) и т.д. (рис. 2).
Рис. 2. Определение смещения позиции буквы относительно начала таблицы
Следует обратить внимание, что представленные в восьмеричной системе счисления коды диапазона русских букв рассматриваемых кодировок отличаются только последними двумя цифрами и имеют общий старший разряд, равный 3 (рис. 3).
Рис. 3. Общий старший разряд восьмеричных кодов русских букв кодировок ср1251 и КОИ-8
Формирование строки кодов реализуется в цикле for (строки 11-15 сценария). В качестве перечисляемых значений здесь выступают элементы массива перекодировки num. Так, на начальной итерации значение варьируемой в цикле переменной i0 будет равно 01 (num [0] = 01), на последней i32 = 21 (num [32] = 21).
На каждой итерации цикла происходит изменение и перезапись значений переменных low и up. Так, в переменную low записывается собственное значение переменной low, полученное на предыдущих итерациях цикла; постоянная часть всех восьмеричных кодов диапазона русских букв \3; значение переменной i (рис. 4).
Рис. 4. Формирование переменной low
В результате в переменную low будет записана строка вида
"\301\302\327\307\304\305\326\332 … \300\321"
Переменная up формируется аналогичным образом с учетом смещения диапазонов кодов заглавных и строчных букв на 408.
Реализованная в строке 16 конкатенация переменных up и low учитывает инверсию диапазонов заглавных и строчных букв кодировок ср1251 и КОИ-8 путем последовательности указания переменных. Команда echo реализует вывод полученной строки и подстановку ее значения в месте вызова функции winkoi.
Так при обработке командой tr буквы А, представленной кодом \03008 (набор ср1251) в исходном файле input.win, в итоговый файл output.koi будет занесено значение кода \03418, соответствующее букве А в кодовом наборе КОИ-8. Таким образом команда tr будет преобразовывать все полученные из исходного файла коды букв русского алфавита (диапазон \3008-\3778), представленные в кодовом наборе ср1251, на соответствующие этим буквам коды набора КОИ-8.