Caracteres visíveis no vi, mas não no gato.

4

Eu tenho um arquivo de 300 linhas com ^@ entre cada caractere no arquivo.

(não posso postar todo o conteúdo por motivos de segurança, portanto estou colando apenas a primeira linha)

[mercury@app01 ftp_logs]$ cat cl.txt
2015-01-22 03:00:01; local;

Agora, quando eu vi o arquivo, vejo o mesmo conteúdo da seguinte forma:

2^@0^@1^@5^@-^@0^@1^@-^@2^@2^@ ^@0^@3^@:^@0^@0^@:^@0^@1^@;^@ ^@l^@o^@c^@a^@l^@;^@

Como cat não estava exibindo os caracteres ^@ , naturalmente achei que o grep para uma determinada string funcionaria em cat , mas, surpreendentemente, não foi.

[mercury@app01 ftp_logs]$ cat cl.txt
2015-01-22 03:00:01; local;
[mercury@app01 ftp_logs]$ cat cl.txt | grep local
[mercury@app01 ftp_logs]$

Após substituir os bytes nulos por sed , o arquivo agora pode ser lido em vi e grep retorna o resultado de cat .

[mercury@app01 ftp_logs]$ sed -i 's/\x0//g' cl.txt
[mercury@app01 ftp_logs]$ cat cl.txt | grep local
2015-01-22 03:00:01; local;
[mercury@app01 ftp_logs]

Perguntas:

1) Por que o grep não funcionou antes de substituir os bytes nulos, já que os bytes nulos não estavam sendo exibidos? Isso significa que grep viu os caracteres ^@ , embora não tenham sido exibidos no terminal?

2) Isso me faz pensar se é recomendado usar cat -v ou vi para ler arquivos em servidores de produção, pois cat parece ser bom em esconder coisas?

3) O arquivo em questão é um arquivo gerado automaticamente a partir de uma máquina Windows. Em que circunstâncias o ^@ encontra seu caminho em um arquivo.

    
por Sree 05.02.2015 / 11:59

2 respostas

4

O formato do arquivo é provavelmente o UTF-16 little-endian. Alguns aplicativos no Windows parecem padrão para isso e causam muitos problemas de porabilidade.

vi representa bytes valorizados ASCII-Nul (numericamente zero) como '^ @' (control-At). Você pode inserir bytes com valor zero em vim com o acorde control-shift- @.

grep deve ver os bytes NII ACII, em vez de interpretar o arquivo como UTF-16 e, em seguida, ver os pontos de código Unicode para '2' ou '0' ou o que for. Eu não vejo uma opção na página GNU grep man para fazer com que ele lide com UTF - qualquer coisa.

cat não mostra os bits ASCII-Nul, o emulador de terminal em questão os mostraria, mas qualquer que seja o emulador de terminal que você esteja usando, estará ignorando-os. Se você usar cat cl.txt | od -x ou melhor, cat cl.txt | xxd , verá os bytes ASCII-Nul na saída de cat . Se você vir algo como 'ffef' ou 'efff' como os dois primeiros bytes do arquivo, eles são o "byte order mark" promulgado pela Microsoft contra todo o senso comum.

Não tenho certeza do que recomendar para transliterar UTF-16 para ASCII ou UTF-8, iconv maybe, mas nunca usei isso.

    
por 05.02.2015 / 15:26
4
  1. Sim, grep sw os caracteres ^@ . cat está imprimindo os caracteres para o terminal, mas eles são caracteres que você não pode ver. Só porque você não pode ver os personagens não significa que eles não estejam lá.

  2. Sua escolha / preferência, dependendo de qual delas funciona melhor para o que você precisa. Lembre-se, no entanto, que vi tem a possibilidade de alterar o arquivo.

  3. ^@ não é um caractere natural. O programa do Windows está ativamente colocando esses personagens lá. Para descobrir o porquê, você teria que perguntar ao programador. Muito provavelmente, o programa do Windows está assumindo que os caracteres têm 16 bits de largura, e sua máquina Unix está assumindo que os caracteres têm 8 bits de largura.

por 05.02.2015 / 12:54