Come rimuovere questo simbolo “^ @” con vim?


58

Ho alcuni file che sono corrotti con questo simbolo:

^ @

Non fa parte della stringa; non è ricercabile. Come posso sostituire questo simbolo con niente o come posso eliminare questo simbolo?

Ecco una riga di esempio da un file:

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

Risposte:


48

Puoi provare:

  • %s/<CTRL-2>//g (su PC normali)

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

dove <CTRL-2>significa premere prima i CTRLnormali PC, tenendolo premuto, premere 2, rilasciare CTRL.

e <CTRL-SHIFT-2>significa premere prima i controlPC Mac, tenendolo premuto, premere i shiftPC Mac, tenendolo premuto, premere 2, rilasciare controle shift.

Infine, entrambi i due comandi dovrebbero risultare %s/^@//gsullo schermo. ^@indica un singolo carattere (un byte NULL, che altrimenti non potrebbe essere visualizzato), non ^seguito da @, quindi non puoi semplicemente digitare ^e @in una riga il comando sopra.

Questo comando rimuove tutto ^@.


3
Mi sono appena imbattuto in questa domanda / risposta attraverso un link correlato: questo è in realtà un cattivo consiglio e funzionerà correttamente solo in pochissimi casi. È meglio cambiare effettivamente la codifica piuttosto che rimuovere byte null. Se rimuovi i byte null, potresti avere ancora altri caratteri multibyte che vengono visualizzati come immondizia.
Mario

@Mario puoi dirci di più sulla modifica della codifica? È qualcosa correlato alla risposta di jrb di seguito?
George

Vedi la risposta di rpyzh più in basso. Mostra il caricamento del file utilizzando la codifica corretta e il salvataggio con un altro (anche se la risposta potrebbe richiedere ulteriori spiegazioni). L'ultima nota di Jrb è sufficiente se vuoi solo leggerlo, ma non se vuoi averlo salvato senza i byte null usando un'altra codifica.
Mario

50

Non penso che i tuoi file siano danneggiati. La riga di esempio sembra contenere un testo normale con byte null tra ogni carattere. Ciò suggerisce che è un file di testo che è stato codificato in UTF-16 ma il segno di ordine dei byte manca all'inizio del file. Vedi http://en.wikipedia.org/wiki/Byte-order_mark

Supponiamo di aprire Blocco note, digitare la parola "nome file" e salvare come Unicode Big-endian. Un dump esadecimale di questo file è simile al seguente:

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

Se apro questo file in Vim sembra a posto - i byte 'fe ff' dicono a Vim come viene codificato il file. Supponiamo ora di creare un file contenente esattamente la stessa sequenza di byte, ma senza il 'fe ff' iniziale. Vim inserisce ^ @ (o <00>, a seconda della configurazione), al posto dei byte null; Blocco note inserisce spazi.

Quindi, piuttosto che rimuovere i null, dovresti davvero cercare di far interpretare correttamente il file da Vim. Puoi ottenere Vim per ricaricare il file con la codifica corretta con il comando:

:e ++enc=utf16


Sì, l'ultimo comando fatto vim interpreta il file correttamente ma non rimuove i nullbyte.
MRT181,

6
Per rimuoverli, scegli un'altra codifica e salva di nuovo il file:: imposta fenc = utf-8
scy

34

Questo in realtà ha funzionato per me all'interno di vim:

:%s/\%x00//g

4
funziona con substitute (), ma Ctl-VCtl-Shift-2 no.
dsummersl,

Lo stesso problema per me, non sono riuscito a far funzionare <Ctrl-V><Ctrl-2>(così come quello con <Ctrl-Shift-2>), ma ha funzionato.
Jeff Bridgman,

4
Questo funziona per me Linux. '00' è il valore ASCII esadecimale, che si possono trovare per ogni personaggio in vim posizionando il cursore su di esso e digitando 'ga' (si pensi "get ascii) in modalità di comando o: come /:. Ascii sulla riga di comando vim .wikia.com / wiki /…
Casey Jones,

^ Vx00 funziona anche. È anche possibile inserire Unicode a 16 bit con ^ VuXXXX. Ho provato \% uXXXX in una ricerca e anche questo ha funzionato.
Edward Falk,

Sarai il mio amato uomo fino alla fine dei tempi. Dal profondo del mio cuore ... grazie!
Gonzalo Cao,

12

Quel "simbolo" rappresenta un carattere NULL, con valore ASCII 000.

È difficile rimuovere con vim, provare

tr -d '\000' < file1 > file2

6

Come altri hanno notato, questi sono byte nulli (ASCII 00). Su Linux, il modo per inserire i valori ASCII in vim è premere Ctrl-V seguito dal valore ottale a 3 cifre di qualsiasi carattere. Per sostituire tutti i byte null, utilizzare:

    :%s/Ctrl-V000//g

(senza spazi).

Allo stesso modo, puoi cercare null con:

    /Ctrl-V000

In entrambi i casi, non mostrerà gli zeri mentre li digiti, ma dopo aver inserito tutti e tre, verrà visualizzato ^@. Sui terminali a colori mostrerà che in blu indica che è un personaggio di controllo.


6

FWIW, nel mio caso ho dovuto usare vim su cygwin per modificare un file di testo creato su un mac. La soluzione accettata non ha funzionato per me, ma era vicina. Secondo la pagina wiki di Vim su come lavorare con Unicode , c'è una differenza tra le versioni Big Endian e Little Endian del byte BOM. Quindi, ho dovuto dire esplicitamente vimdi usare una versione Little Endian della codifica BOM.

Solo dopo aver scelto la codifica corretta ho convertito il formato del file (terminazioni di riga) in dosmodo da poter modificare il file nell'editor di Windows. Cercare di reimpostare il formato del file prima di specificare la codifica mi ha dato dolore. Ecco l'elenco completo dei comandi che ho usato:

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

Informazioni preziose. Nel mio caso era l'endianità del byte DBA.
Andre Albuquerque,

3

La soluzione accettata non ha funzionato per me. trInvece ho creato il file vim pipe :

:%!tr -d '\000'

Funzionerebbe bene anche con la modalità visiva (basta digitare :!tr -d '\000') o su una gamma di linee:

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

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

2

^@ non è un brutto carattere se si utilizza una codifica corretta, ma se si desidera rimuovere, provare:

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

^ Il carattere M è presente nei dati di esempio

Per convertire il tuo file in formato Unix / Linux prima di qualsiasi elaborazione, prova:

dos2unix filename - rhel e altri

dos2ux filename [newfilename] - HP-UX


1

Oltre alla risposta di @ jrb, in Vim, la codifica dei caratteri del file viene rilevata in base all'opzione di codifica dei file. (notare la 's' alla fine della codifica dei file)

Vale a dire su Windows, il valore predefinito per l' fileencodingsopzione è ucs-bom, che significa:

controlla se esiste una DBA all'inizio del file.

Se esiste una DBA, "leggi la codifica dei caratteri del file dalla DBA".

Se la BOM non esiste (e in questo caso ciò significherebbe anche che tutte le codifiche dei caratteri specificate fileencodingsnell'opzione non sono riuscite a corrispondere), quindi leggere il file con la codifica dei caratteri specificata encodingnell'opzione. La codifica dei caratteri di default per l' encodingopzione è: latin1. Ora, poiché latin1è la codifica dei caratteri di lunghezza di un byte , tutti i byte nel file sono latin1caratteri validi (anche il Nulcarattere ^@che vedi *).

* - in realtà, ^@è il carattere di nuova riga nel testo del buffer di Vim, non il carattere Nul.

Il modo corretto di leggere il file è specificare la codifica dei caratteri manualmente come UTF-16 (poiché sembra che UTF-16 sia la codifica dei caratteri corretta in questo caso).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.