Inspirado poressa questão, posso usar o iconv
comando para gerar saída UTF-16 com uma BOM e com endianness especificado?
O iconv
comando converte texto de uma codificação para outra.
Por exemplo:
echo hello | iconv -f ascii -t utf-16
gera uma representação UTF-16 de "hello\n"
.
Os arquivos UTF-16 geralmente, mas nem sempre, começam com uma Byte Order Mark (BOM), que é uma codificação de 2 bytes do caractere Unicode U+FEFF
. Você pode determinar o endianness de um arquivo UTF-16 com BOM verificando se os dois primeiros bytes são FE FF
ou FF FE
.
O iconv
comando possui diversas opções para gerar saída UTF-16:
$ iconv --list | grep -i utf-16
UTF-16//
UTF-16BE//
UTF-16LE//
Este comando:
echo hello | iconv -f ascii -t utf-16be
gera UTF-16 big-endiansem lista técnica; parece assumir que se você especificou o endianness, não precisa indicá-lo na saída. Da mesma forma, utf-16le
gera UTF-16 little-endian sem BOM.
Esse:
echo hello | iconv -f ascii -t utf-16
gera (no meu sistema Ubuntu x86) little-endian UTF-16comuma lista técnica - mas vi um relatório de um comando semelhante gerando UTF-16 big-endian com uma lista técnica, mesmo em um sistema little endian.
Sempre posso usar utf-16be
ou utf-16le
e preceder a lista técnica manualmente, mas estou procurando uma solução que use apenas o iconv
comando.
Outra solução alternativa,sevocê sabe o que o endianness -t utf-16
gera, é:
echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null
Qual identificaçãocomousar é algo como:
iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM
mas iconv
não suporta isso.
EDITAR:
Alguém com acesso a um sistema Mac OSX x86 pode postar um comentário mostrando a saída (copiada e colada) do seguinte comando?
echo hello | iconv -f ascii -t utf-16 | od -x
Responder1
Não, se você especificar a ordem de bytes, iconv
não inserirá uma BOM.
Isto é deO Consórcio Unicode
P: Como devo lidar com BOMs?
R: Aqui estão algumas diretrizes a serem seguidas:
- Um protocolo específico (por exemplo, convenções da Microsoft para arquivos .txt) pode exigir o uso da BOM em determinados fluxos de dados Unicode, como arquivos. Quando você precisar estar em conformidade com esse protocolo, use uma lista técnica.
- Alguns protocolos permitem BOMs opcionais no caso de texto não marcado. Nesses casos,
- Onde um fluxo de dados de texto é conhecido como texto simples, mas de codificação desconhecida, a BOM pode ser usada como uma assinatura. Se não houver BOM, a codificação poderá ser qualquer coisa.
- Onde um fluxo de dados de texto é conhecido como texto Unicode simples (mas não qual endian), então a lista técnica pode ser usada como uma assinatura. Se não houver BOM, o texto deverá ser interpretado como big-endian.
- Alguns protocolos orientados a bytes esperam caracteres ASCII no início de um arquivo. Se UTF-8 for usado com esses protocolos, o uso do BOM como assinatura do formulário de codificação deverá ser evitado.
- Quando o tipo preciso do fluxo de dados for conhecido (por exemplo, Unicode big-endian ou Unicode little-endian), a lista técnica não deverá ser usada. Em particular, sempre que um fluxo de dados é declarado como UTF-16BE, UTF-16LE, UTF-32BE ou UTF-32LE uma lista técnicaNão deveser usado.
(minha ênfase)
Espero que você iconv
esteja tentando ser fiel à última dessas diretrizes.
Atualizar.
Uma digressão
Na minha opinião:
Uma opção para especificar uma lista técnica certamente seria um recurso adicional útil para o iconv.
Um arquivo UTF-16LE sem BOMéutilizável no Windows, embora às vezes com esforço adicional. Por exemplo, a caixa de diálogo Abrir arquivo do Bloco de notas permite selecionar "Unicode", que é o nome da Microsoft para "UTF-16LE" e (sem surpresa) parece funcionar em arquivos sem BOM.
Posso abrir um arquivo de teste UTF-16LE (sem BOM) ou um arquivo de teste UTF-8 (sem BOM) no Windows Notepad (XP) da maneira usual, por exemplo, clicando duas vezes no nome do arquivo no Explorer. Isso parece utilizável para mim. Estou ciente de que às vezes o Windows adivinha a codificação incorretamente. Nesse caso, você deve informar a codificação ao Bloco de Notas ao abrir o arquivo. Esse inconveniente significa que é preferível incluir uma lista técnica para arquivos de texto destinados ao uso no Windows.
Se um aplicativo específico não funcionar com nada além de um arquivo UTF-16LE com BOM, concordo que um arquivo UTF-16LE sem BOM não poderá ser usado para esse aplicativo específico.
Eu suspeito quesevocê pode fazer tudo funcionar com UTF-8 (sem BOM), que é a melhor solução a longo prazo.
No entanto, a resposta à pergunta "posso usar o comando iconv para gerar saída UTF-16 com uma BOM e com endianness especificado"é atualmente"Não".
Responder2
Se quiser adicionar a BOM a um arquivo, você pode adicioná-la manualmente:
Para BOM UTF-8 (EF BB BF)
file='main.cpp'
printf '\xEF\xBB\xBF' > $file.utf8
iconv -f ASCII -t UTF-8 $file >> $file.utf8
mv -v $file.utf8 "converted-$file"
Para BOM UTF-16BE (FE FF)
file='main.cpp'
printf '\xFE\xFF' > $file.utf16be
iconv -f ASCII -t UTF-16BE $file >> $file.utf16be
mv -v $file.utf16be "converted-$file"
Para BOM UTF-16LE (FF FE)
file='main.cpp'
printf '\xFF\xFE' > $file.utf16le
iconv -f ASCII -t UTF-16LE $file >> $file.utf16le
mv -v $file.utf16le "converted-$file"
Observação:
Provavelmente você notou que a lista técnica em cada caso é diferente. Você pode encontrarmais informações aqui: