Eu já notei que se você pegar texto codificado em ASCII (ou, equivalentemente, texto ASCII codificado em UTF-8) e decodificá-lo como UTF-16, você frequentemente recebe “caracteres chineses” (diferentes dependendo de decodificá-lo) como UTF-16BE ou UTF-16LE). Com base nisso, acho que você está lidando com codificações mistas. Meu palpite é que Commision.txt
é codificado como UTF-16BE ou UTF-16LE, que question.txt
é ASCII simples (ou ASCII codificado em UTF-8) e que seu newFile
acaba como uma combinação inválida das codificações dos dois arquivos.
As coisas devem funcionar melhor se você usar a mesma codificação em ambos os arquivos; Provavelmente, o UTF-8 funcionará melhor. Se você precisa que a saída final esteja em alguma outra codificação, então você pode usar iconv para convertê-la ( iconv -f UTF-8 -t UTF-16BE <newFile >newfile.utf16be.txt
).
Efetivamente, a codificação UTF-16 de caracteres ASCII é igual à codificação ASCII, mas com caracteres NUL extras inseridos entre cada caractere ASCII junto com mais um NUL antes ou depois de todo o lote (dependendo do endian do UTF- 16 codificação). Isso significa que o texto ASCII codificado como UTF-8 ou UTF-16 parecerá "normal" quando visualizado diretamente em um terminal UTF-8 (ou seja, "imprimir em um console").
Contanto que o conteúdo do arquivo seja mantido separado, qualquer ambiente de visualização de detecção de codificação (por exemplo, um editor) provavelmente detectará corretamente a codificação (ou pelo menos escolherá um que seja suficientemente próximo considerando que UTF-8 e muitos byte único codificações são idênticas na faixa ASCII).
Mas, você tem sed misturando os arquivos juntos. Infelizmente, sed não é “inteligente” o suficiente para perceber que está lidando com arquivos usando duas codificações de texto diferentes. Você acaba com (de acordo com meu palpite) um arquivo que é principalmente codificado em UTF-16 (de Commision.txt
) com uma seção codificada em UTF-8 (de question.txt
) no meio (ou onde quer que seu Q
o coloque) ). O resultado é provavelmente inválido se totalmente decodificado como UTF-8, mas possivelmente válido quando totalmente decodificado como UTF-16 (embora com alguns conteúdos inesperados onde os dados UTF-8 são).
Aqui está um exemplo:
Commision.txt
é ASCII codificado em UTF-16BE (com uma BOM).
% xxd Commision.txt
0000000: feff 0046 0069 0072 0073 0074 0020 006c ...F.i.r.s.t. .l
0000010: 0069 006e 0065 000a 004c 0069 006e 0065 .i.n.e...L.i.n.e
0000020: 0020 0077 0069 0074 0068 0020 0061 0020 . .w.i.t.h. .a.
0000030: 0075 0063 0020 0027 0071 0027 003a 0020 .u.c. .'.q.'.:.
0000040: 0028 0051 0029 000a 004c 0061 0073 0074 .(.Q.)...L.a.s.t
0000050: 0020 006c 0069 006e 0065 000a . .l.i.n.e..
question.txt
é ASCII (ou ASCII codificado em UTF-8).
% xxd question.txt
0000000: 5768 6174 2069 7320 7468 6520 6169 722d What is the air-
0000010: 7370 6565 6420 7665 6c6f 6369 7479 206f speed velocity o
0000020: 6620 616e 2075 6e6c 6164 656e 2073 7761 f an unladen swa
0000030: 6c6c 6f77 3f0a llow?.
Eu os combino com sed .
% sed '/Q/{
s/Q//g
r question.txt
}' Commision.txt >newFile
newFile
é uma bagunça.
sed excluiu o Q
como um único byte ( 51
) em vez de sua representação de dois bytes UTF-16 ( 00 51
).
Isso estraga o alinhamento de dois bytes do restante do arquivo, fornece um comprimento inteiro que é ímpar em vez de igual e introduz um UTF-16 NULL ( 0000
).
% xxd newFile
0000000: feff 0046 0069 0072 0073 0074 0020 006c ...F.i.r.s.t. .l
0000010: 0069 006e 0065 000a 004c 0069 006e 0065 .i.n.e...L.i.n.e
0000020: 0020 0077 0069 0074 0068 0020 0061 0020 . .w.i.t.h. .a.
0000030: 0075 0063 0020 0027 0071 0027 003a 0020 .u.c. .'.q.'.:.
0000040: 0028 0000 2900 0a57 6861 7420 6973 2074 .(..)..What is t
0000050: 6865 2061 6972 2d73 7065 6564 2076 656c he air-speed vel
0000060: 6f63 6974 7920 6f66 2061 6e20 756e 6c61 ocity of an unla
0000070: 6465 6e20 7377 616c 6c6f 773f 0a00 4c00 den swallow?..L.
0000080: 6100 7300 7400 2000 6c00 6900 6e00 6500 a.s.t. .l.i.n.e.
0000090: 0a .
Apesar da bagunça, parece bem no meu terminal UTF-8.
% cat newFile
First line
Line with a uc 'q': ()
What is the air-speed velocity of an unladen swallow?
Last line
Quando eu carrego no Vim, no entanto as coisas estão obviamente erradas (na verdade existe um NUL após o parêntese aberto, mas sua presença fez com que este post fosse truncado). Vim avisa "CONVERSION ERROR na linha 2".
First line
Line with a uc 'q': (⤀桡琠楳⁴桥楲灥敤⁶敬潣楴礠潦渠畮污摥渠獷慬汯眿䰀愀猀琀 氀椀渀攀
Se eu excluir o ponto de interrogação de question.txt
(para fornecer um número par de bytes novamente) e gerar novamente newFile
, obtenho a última linha "de volta" (embora esteja preso ao final da segunda linha ) e evitar o aviso de conversão do Vim.
First line
Line with a uc 'q': (⤀桡琠楳⁴桥楲灥敤⁶敬潣楴礠潦渠畮污摥渠獷慬汯眊Last line