Como remover este símbolo “^ @” com o vim?


59

Eu tenho alguns arquivos que estão corrompidos com este símbolo:

^ @

Não faz parte da cadeia; não é pesquisável. Como substituo este símbolo por nada ou como excluo este símbolo?

Aqui está um exemplo de linha de um arquivo:

^@F^@i^@l^@e^@n^@a^@m^@e^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@ ^@:^@ ^@^M^@

Respostas:


51

Você poderia tentar:

  • %s/<CTRL-2>//g (em computadores comuns)

  • %s/<CTRL-SHIFT-2>//g (em PCs Mac)

onde <CTRL-2>significa primeiro pressionar os CTRLPCs comuns, mantendo-os pressionados, pressionando 2, solte CTRL.

e <CTRL-SHIFT-2>significa primeiro pressionar os controlMac PCs, mantendo pressionado, pressionar shiftMac Macs, mantendo pressionado, pressionar 2, soltar controle shift.

Finalmente, os dois comandos devem resultar na %s/^@//gtela. ^@significa um único caractere (um byte NULL, que de outra forma não poderiam ser exibidos), não ^seguido de @, então você não pode simplesmente digitar ^e @em uma linha no comando acima.

Este comando remove todos os ^@.


4
Acabei de encontrar esta pergunta / resposta através de um link relacionado: Este é realmente um mau conselho e só funcionará corretamente em pouquíssimos casos. É melhor alterar a codificação, em vez de remover bytes nulos. Se você remover os bytes nulos, ainda poderá ter outros caracteres multibyte que aparecem como lixo.
— 7273 Mario

@ Mario, você poderia nos falar mais sobre a alteração na codificação? É algo relacionado à resposta do jrb abaixo?
— George

Veja a resposta de rpyzh mais abaixo. Mostra o carregamento do arquivo usando a codificação adequada e o salvando com um código diferente (embora a resposta possa precisar de mais explicações). A última nota do Jrb é suficiente se você quiser apenas lê-la, mas não se quiser salvá-la sem os bytes nulos usando outra codificação.
— Mario

50

Eu não acho que seus arquivos estão corrompidos. Sua linha de exemplo parece conter texto normal com bytes nulos entre cada caractere. Isso sugere que é um arquivo de texto codificado em UTF-16, mas a marca de ordem dos bytes está ausente desde o início do arquivo. Veja http://en.wikipedia.org/wiki/Byte-order_mark

Suponha que eu abra o Bloco de notas, digite a palavra 'nome do arquivo' e salve como Bigode end-Unicode. Um despejo hexadecimal desse arquivo se parece com o seguinte:

fe ff 00 66 00 69 00 6c 00 65 00 6e 00 61 00 6d 00 65

Se eu abrir esse arquivo no Vim, ele ficará bem - os bytes 'fe ff' informam ao Vim como o arquivo é codificado. Agora, suponha que eu crie um arquivo contendo exatamente a mesma sequência de bytes, mas sem o primeiro 'fe ff'. O Vim insere ^ @ (ou <00>, dependendo da sua configuração), no lugar dos bytes nulos; O bloco de notas insere espaços.

Portanto, em vez de remover os nulos, você deve realmente procurar que o Vim interprete o arquivo corretamente. Você pode fazer com que o Vim recarregue o arquivo com a codificação correta com o comando:

:e ++enc=utf16


Sim, o último comando feito no vim interpreta o arquivo corretamente, mas não remove os bytes nulos.
— mrt181

6
Para removê-los, escolha outra codificação e salve o arquivo novamente:: set FENC = utf-8
— Scy

35

Isso realmente funcionou para mim no vim:

:%s/\%x00//g

5
isso funciona com substituto (), mas Ctl-VCtl-Shift-2 não.
— precisa saber é o seguinte

Mesmo problema para mim, também não consegui trabalhar <Ctrl-V><Ctrl-2>(além da pessoa com <Ctrl-Shift-2>), mas isso funcionou.
— 31813 Jeff Bridgman

5
Isso funciona para mim linux. '00' é o valor ASCII hex, onde pode encontrar para qualquer personagem no vim, colocando o cursor sobre ele e digitando 'ga' (acho que "obter ascii) no modo de comando ou: como /:. Ascii na linha de comando vim .wikia.com / wiki /…
— Casey Jones

^ Vx00 também funciona. Você também pode inserir o unicode de 16 bits com ^ VuXXXX. Eu tentei \% uXXXX em uma pesquisa e isso também funcionou.
— Edward Falk,

Você será meu homem amado até o fim dos tempos. Do fundo do meu coração ... obrigado!
— Gonzalo Cao

12

Esse 'símbolo' representa um caractere NULL, com valor ASCII 000.

É difícil remover com o vim, tente

tr -d '\000' < file1 > file2

7

Como outros observaram, esses são bytes nulos (ASCII 00). No Linux, a maneira de inserir valores ASCII no vim é pressionar Ctrl-V seguido pelo valor octal de 3 dígitos de qualquer caractere. Para substituir todos os bytes nulos, use:

    :%s/Ctrl-V000//g

(sem espaços).

Da mesma forma, você pode procurar nulos com:

    /Ctrl-V000

Nos dois casos, ele não mostrará os zeros enquanto você os digita, mas depois de inserir os três, será exibido ^@. Nos terminais coloridos, mostrará isso em azul para indicar que é um caractere de controle.


6

FWIW, no meu caso, tive que usar o vim no cygwin para editar um arquivo de texto criado em um mac. A solução aceita não funcionou para mim, mas estava próxima. De acordo com a página wiki do Vim sobre como trabalhar com Unicode , há uma diferença entre as versões Big Endian e Little Endian do byte da BOM. Então, eu tive que dizer explicitamente vimpara usar uma versão Little Endian da codificação de BOM.

Somente depois de escolher a codificação correta, converti o formato do arquivo (finais de linha) para dosque eu pudesse editar o arquivo no editor do Windows. Tentar definir redefinir o formato do arquivo antes de especificar a codificação me deixou triste. Aqui está a lista completa de comandos que eu usei:

:e ++enc=utf16le
:w!
:e ++ff=mac
:setlocal ff=dos
:wq

Informações preciosas. No meu caso, era o endianness do byte da BOM.
— Andre Albuquerque

3

A solução aceita não funcionou para mim. Eu fiz o vim canalizar o arquivo em trvez disso:

:%!tr -d '\000'

Isso também funcionaria bem com o modo visual (apenas digitar :!tr -d '\000') ou em várias linhas:

# Remove nulls from current line:
:.!tr -d '\000'

# Remove nulls from lines 3-5:
:3,5!tr -d '\000'

2

^@ não é um caractere ruim se você usar uma codificação adequada, mas se desejar remover, tente:

  • tr -d '\000'
  • sed 's/\000//g'

^ O caractere M está presente nos dados de exemplo

Para converter seu arquivo para o formato Unix / Linux antes de qualquer processamento, tente:

dos2unix filename - rhel e outros

dos2ux filename [newfilename] - HP-UX


1

Além da resposta do @ jrb, no Vim, a codificação de caracteres do arquivo é detectada com base na opção codificação de arquivos. (observe os 's' no final das codificações de arquivo)

Ou seja, no Windows, o valor padrão para a fileencodingsopção é ucs-bom, o que significa:

verifique se a lista técnica existe no início do arquivo.

Se a lista técnica existir, 'leia a codificação de caracteres do arquivo fora da lista técnica'.

Se a BOM não existir (e, nesse caso, isso também significaria que todas as codificações de caracteres especificadas na fileencodingsopção falharam em corresponder), leia o arquivo com a codificação de caracteres especificada na encodingopção. A codificação de caracteres padrão para a encodingopção é: latin1. Agora, como latin1é a codificação de caracteres de um byte , todos os bytes no arquivo são latin1caracteres válidos (mesmo o Nulcaractere ^@que você está vendo *).

* - na verdade, ^@é o caractere de nova linha no texto do buffer do Vim, não o caractere Nul.

A maneira correta de ler o arquivo é especificar a codificação de caracteres manualmente como UTF-16 (pois parece que UTF-16 é a codificação char apropriada nesse caso).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.