Использование sed для разброса нулевых байтов - PullRequest
1 голос
/ 05 июля 2011

Я хочу использовать sed, чтобы взять любой произвольный поток и добавить нулевой байт к каждому байту.

Я пробовал несколько вещей, но у меня возникли проблемы с:

  1. соответствует любому байту - . кажется подмножеством, то есть любым символом, а не байтом.
  2. добавление нулевого байта - я думал, что это должно быть \0, но это не работает.

Ответы [ 2 ]

4 голосов
/ 05 июля 2011

Ответ на оригинальный вопрос

Я предлагаю использовать Perl или Python;Вот (подробное) решение Perl:

#!/usr/bin/env perl
use strict;
use warnings;
while (<>)
{
    s/./$&\0/gs;
    print;
}

Для ввода текста ASCII это дает вывод UTF-16LE (без спецификации).Учитывая, что это Perl, TMTOWTDI, и его можно сократить до одной строки;см. ответ по paxdiablo .

Учитывая эту явную структуру цикла, самый простой способ напечатать спецификацию - добавить оператор печати перед циклом:

printf "%c%c", 0xFF, 0xFE;

При однострочности вам необходим блок BEGIN:

perl -pe 'BEGIN{printf "%c%c", 0xFF, 0xFE;} s/(.)/\1\0/gs;' "$@"

В этом скрипте есть как минимум 4, возможно, 5 лишних пробела.


Ответ на пересмотренный и затем перевернутый вопрос

Измененный вопрос был:

Я хочу использовать sed, чтобы взять любой произвольный поток UTF-8 и добавить нулевой байт, преобразовав его в каждыйбайт UTF-16.Какой волшебный соус, чтобы это произошло?

Пересмотренный вопрос очень отличается от оригинала.Преобразование UTF-8 в UTF-16, в общем, является умеренно сложным;Вы должны прочитать 1-4 байта ввода и сгенерировать 2 или 4 байта вывода, беспокоясь о суррогатах и ​​неправильном вводе, и т. д. Оригинальный вопрос - как добавить NUL (или ноль) байт после каждого символа на входе -намного, намного, намного проще.(Остается верным, что если входными данными являются ASCII - 7-битные значения байтов в диапазоне от 0 до 127 - тогда «добавить NUL впоследствии» дает вам UTF-16LE. Но только если данные UTF-8 находятся в подмножестве ASCII.)

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

Usage: iconv [OPTION...] [-f ENCODING] [-t ENCODING] [INPUTFILE...]
or:    iconv -l

Converts text from one encoding to another encoding.

Options controlling the input and output format:
  -f ENCODING, --from-code=ENCODING
                              the encoding of the input
  -t ENCODING, --to-code=ENCODING
                              the encoding of the output

Options controlling conversion problems:
  -c                          discard unconvertible characters
  --unicode-subst=FORMATSTRING
                              substitution for unconvertible Unicode characters
  --byte-subst=FORMATSTRING   substitution for unconvertible bytes
  --widechar-subst=FORMATSTRING
                              substitution for unconvertible wide characters

Options controlling error output:
  -s, --silent                suppress error messages about conversion problems

Informative output:
  -l, --list                  list the supported encodings
  --help                      display this help and exit
  --version                   output version information and exit

Следовательно, для преобразования из UTF-8 в UTF-16LE:

iconv -f UTF-8 -t UTF-16LE  input > output

Интересно, что я не вижу опции для добавления спецификации к выводу, по крайней мере, не в iconv версии 1.11 от 2007 года на RHEL 5 (ни на той же версии на MacOS X от 2006 года - неспроси, я не знаю!).

2 голосов
/ 05 июля 2011

Если у вас есть Perl, вы можете использовать однострочник:

perl -pe 's/(.)/\1\0/gs'

чтобы сделать это для каждого персонажа. Оставьте s в конце, если вы хотите, чтобы переводы строк были сохранены как есть (но, похоже, вы хотите, чтобы и строки тоже были сделаны).

Следующая запись показывает это в действии:

pax$ echo hello | perl -pe 's/(.)/\1\0/g' | od -xcb
0000000    0068    0065    006c    006c    006f    000a
          h  \0   e  \0   l  \0   l  \0   o  \0  \n
        150 000 145 000 154 000 154 000 157 000 012
0000013

pax$ echo hello | perl -pe 's/(.)/\1\0/gs' | od -xcb
0000000    0068    0065    006c    006c    006f    000a
          h  \0   e  \0   l  \0   l  \0   o  \0  \n  \0
        150 000 145 000 154 000 154 000 157 000 012 000
0000014
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...