¿Cómo eliminar este símbolo "^ @" con vim?

59

Tengo algunos archivos que están dañados con este símbolo:

^ @

No es parte de la cadena; No se puede buscar. ¿Cómo puedo sustituir este símbolo por nada o cómo elimino este símbolo?

Aquí hay una línea de ejemplo de un archivo:

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

Respuestas:

51

Tu podrías intentar:

  • %s/<CTRL-2>//g (en PC normales)

  • %s/<CTRL-SHIFT-2>//g (en PC Mac)

donde <CTRL-2>significa presionar primero la CTRLPC normal, manteniéndola presionada, presionar 2, soltar CTRL.

y <CTRL-SHIFT-2>significa primero presionar hacia abajo controlen las PC Mac, manteniéndola presionada, presionar hacia abajo shiften las PC Mac, manteniéndola presionada, presionar 2, soltar controly shift.

Finalmente, los dos comandos deberían aparecer en la %s/^@//gpantalla. ^@significa un solo carácter (un byte NULL, que de otro modo no podría mostrarse), no ^seguido @, por lo que no puede simplemente escribir ^y @en una fila en el comando anterior.

Este comando elimina todo el ^@.

phresus
fuente
44
Me topé con esta pregunta / respuesta a través de un enlace relacionado: este es realmente un mal consejo y solo funcionará correctamente en muy pocos casos. Es mejor cambiar realmente la codificación en lugar de eliminar bytes nulos. Si elimina los bytes nulos, es posible que aún tenga otros caracteres multibyte que se muestran como basura.
Mario
@ Mario, ¿podría contarnos más sobre el cambio de codificación? ¿Es algo relacionado con la respuesta de jrb a continuación?
George
Vea la respuesta de rpyzh más abajo. Muestra cómo cargar el archivo con la codificación adecuada y guardarlo con uno diferente (aunque la respuesta podría necesitar más explicaciones). La última nota de Jrb es suficiente si solo desea leerla, pero no si desea guardarla sin los bytes nulos utilizando otra codificación.
Mario
50

No creo que tus archivos estén dañados. Parece que su línea de ejemplo contiene texto normal con bytes nulos entre cada carácter. Esto sugiere que es un archivo de texto que ha sido codificado en UTF-16 pero que falta la marca de orden de bytes desde el inicio del archivo. Ver http://en.wikipedia.org/wiki/Byte-order_mark

Supongamos que abro el Bloc de notas, escribo la palabra 'nombre de archivo' y lo guardo como Unicode Big-endian. Un volcado hexadecimal de este archivo se ve así:

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

Si abro este archivo en Vim, se ve bien: los bytes 'fe ff' le dicen a Vim cómo se codifica el archivo. Ahora suponga que creo un archivo que contiene exactamente la misma secuencia de bytes, pero sin el principal 'fe ff'. Vim inserta ^ @ (o <00>, dependiendo de su configuración), en lugar de los bytes nulos; El bloc de notas inserta espacios.

Entonces, en lugar de eliminar los valores nulos, realmente debería buscar que Vim interprete el archivo correctamente. Puede hacer que Vim vuelva a cargar el archivo con la codificación correcta con el comando:

:e ++enc=utf16

jrb
fuente
Sí, el último comando hizo que vim interprete el archivo correctamente pero no elimina los nullbytes.
mrt181
66
Para eliminarlos, elija otra codificación y guarde el archivo nuevamente:: set fenc = utf-8
scy
35

Esto realmente funcionó para mí dentro de vim:

:%s/\%x00//g
jriggins
fuente
55
esto funciona con sustituto (), pero Ctl-VCtl-Shift-2 no.
dsummersl
El mismo problema para mí, tampoco pude conseguir <Ctrl-V><Ctrl-2>(al igual que el que tenía <Ctrl-Shift-2>), pero esto funcionó.
Jeff B
55
Esto funciona para mí Linux. '00' es el valor hexadecimal ASCII, que puede encontrar para cualquier carácter en vim colocando el cursor sobre él y escribiendo 'ga' (piense "get ascii) en modo comando o: as /: ascii en la línea de comando. Vim .wikia.com / wiki / ...
Casey Jones
^ Vx00 también funciona. También puede ingresar unicode de 16 bits con ^ VuXXXX. Intenté \% uXXXX en una búsqueda y eso también funcionó.
Edward Falk
Serás mi amado hasta el fin de los tiempos. Desde lo profundo de mi corazón ... ¡gracias!
Gonzalo Cao
12

Ese 'símbolo' representa un carácter NULO, con valor ASCII 000.

Es difícil de eliminar con vim, prueba

tr -d '\000' < file1 > file2
pavium
fuente
7

Como otros han señalado, esos son bytes nulos (ASCII 00). En Linux, la forma de ingresar valores ASCII en vim es presionar Ctrl-V seguido del valor octal de 3 dígitos de cualquier carácter. Para reemplazar todos los bytes nulos, use:

    :%s/Ctrl-V000//g

(sin espacios).

Del mismo modo, puede buscar nulos con:

    /Ctrl-V000

En ambos casos, no mostrará los ceros mientras los escribe, pero después de ingresar los tres, se mostrará ^@. En los terminales de color lo mostrará en azul para indicar que es un personaje de control.

TheAmigo
fuente
6

FWIW, en mi caso tuve que usar vim en cygwin para editar un archivo de texto creado en una mac. La solución aceptada no funcionó para mí, pero estaba cerca. Según la página wiki de Vim sobre trabajar con Unicode , existe una diferencia entre las versiones Big Endian y Little Endian del byte BOM. Entonces, tuve que decirle explícitamente vimque usara una versión Little Endian de la codificación BOM.

Solo después de elegir la codificación correcta, convertí el formato de archivo (terminaciones de línea) para dospoder editar el archivo en el editor de Windows. Tratar de restablecer el formato del archivo antes de especificar la codificación me dio pena. Aquí está la lista completa de comandos que utilicé:

:e ++enc=utf16le
:w!
:e ++ff=mac
:setlocal ff=dos
:wq
rpyzh
fuente
Información preciosa En mi caso fue el endianness del byte BOM.
Andre Albuquerque
3

La solución aceptada no funcionó para mí. En su lugar, hice que vim canalice el archivo tr:

:%!tr -d '\000'

Esto también funcionaría bien con el modo visual (solo escriba :!tr -d '\000') o en un rango de líneas:

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

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

^@ no es un mal carácter si usa una codificación adecuada, pero si desea eliminarlo, intente:

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

^ M carácter está ahí en sus datos de ejemplo

Para convertir su archivo a formato Unix / Linux antes de cualquier procesamiento, intente:

dos2unix filename - rhel y otros

dos2ux filename [newfilename] - HP-UX

user490343
fuente
1

Además de la respuesta de @ jrb, en Vim, la codificación de caracteres del archivo se detecta en función de la opción de codificación de archivos. (tenga en cuenta la 's' al final de las codificaciones de archivo)

Es decir, en Windows, el valor predeterminado para la fileencodingsopción es ucs-bom, lo que significa:

compruebe si existe una lista de materiales al comienzo del archivo.

Si existe BOM, entonces 'lea la codificación de caracteres del archivo fuera de BOM'.

Si BOM no existe (y en este caso eso también significaría que todas las codificaciones de caracteres especificadas en la fileencodingsopción no coincidieron), entonces lea el archivo con la codificación de caracteres especificada en la encodingopción. La codificación de caracteres por defecto de la encodingopción es: latin1. Ahora, debido a que latin1es la codificación de caracteres de longitud de un byte , todos los bytes en el archivo son latin1caracteres válidos (incluso el Nulcarácter ^@que está viendo *).

* - en realidad, ^@es el carácter de nueva línea en el texto del búfer de Vim, no el carácter Nul.

La forma correcta de leer el archivo es especificar la codificación de caracteres manualmente como UTF-16 (ya que parece que UTF-16 es la codificación de caracteres adecuada en este caso).

colemik
fuente