Потоковый файл UTF-16 с окончаниями строк спецификации и Unix в Windows Perl - PullRequest
0 голосов
/ 26 февраля 2012

Мне нужно выполнить потоковую обработку, используя perl текстовый файл 1 Гб, закодированный в порядке байтов UTF-16 с окончанием в стиле Unix (то есть 0x000A только без 0x000D в потоке) и LE BOM в начале. Файл обрабатывается в Windows (также необходимы решения Unix). Под потоковым процессом я подразумеваю использование while (<>), построчное чтение и запись. Было бы неплохо, чтобы в командной строке была одна строка:
perl -pe "BEGIN {SOME_PREPARATION}; s / SRC / DST / g;" infile.txt> outfile.txt

Шестнадцатеричный дамп ввода для тестирования (две строки: буквы "a" и "b" на каждой): FF FE 61 00 0A 00 62 00 0A 00

обработка, подобная s / b / c / g , должна дать вывод («b» заменяется на «c»): FF FE 61 00 0A 00 63 00 0A 00

PS. Прямо сейчас со всеми моими испытаниями либо есть проблема с выводом CRLF (0D 0A байт выводятся с неправильным символом Юникода, и мне нужно только 0A00 без 0D00, чтобы сохранить тот же стиль Unix), либо каждая новая строка переключает LE / BE, т.е. "на одной строке - 6100 на нечетных строках и 0061 на четных строках в выводе.

1 Ответ

3 голосов
/ 26 февраля 2012

Лучшее, что я придумал, это:

perl -pe "BEGIN { binmode $_, ':raw:encoding(UTF-16LE)' for *STDIN, *STDOUT }; s/b/c/g;" <infile.txt >outfile.txt

Но учтите, что мне пришлось использовать <infile.txt вместо infile.txt, чтобы файл находился на STDIN. Теоретически, прагма open должна управлять кодировкой, используемой волшебным ARGV файловым дескриптором, но я не могу заставить его работать правильно в этом случае.

Разница между <infile.txt и infile.txt заключается в том, как и когда файлы открываются. При <infile.txt файл подключается к стандартному вводу и открывается до запуска Perl. Когда вы binmode STDIN в блоке BEGIN, файл уже открыт, и вы можете изменить кодировку.

Когда вы используете infile.txt, имя файла передается в качестве аргумента командной строки и помещается в массив @ARGV. Когда выполняется блок BEGIN, файл еще не открыт, поэтому вы не можете установить его кодировку. Теоретически, вы должны быть в состоянии сказать:

use open qw(:std IO :raw:encoding(UTF-16LE));

и волшебная обработка <ARGV> применяет правильную кодировку. Но я не смог заставить это работать правильно в этом случае.

...