Wie entferne ich dieses Symbol "^ @" mit vim?

59

Ich habe einige Dateien, die mit diesem Symbol beschädigt sind:

^ @

Es ist nicht Teil der Zeichenfolge; es ist nicht durchsuchbar. Wie ersetze ich dieses Symbol durch nichts oder wie lösche ich dieses Symbol?

Hier ist eine Beispielzeile aus einer Datei:

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

Antworten:

51

Du könntest es versuchen:

  • %s/<CTRL-2>//g (auf normalen PCs)

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

Wobei <CTRL-2>bedeutet CTRL, dass Sie bei normalen PCs zuerst die Taste drücken, gedrückt halten, drücken und 2loslassen CTRL.

und <CTRL-SHIFT-2>bedeutet, zuerst controlauf Mac-PCs drücken und gedrückt halten, dann shiftauf Mac-PCs drücken und gedrückt halten, drücken 2, loslassen controlund shift.

Schließlich sollten beide Befehle %s/^@//gauf dem Bildschirm angezeigt werden. ^@bedeutet ein einzelnes Zeichen (ein NULL - Byte, die sonst nicht angezeigt werden), nicht ^gefolgt @, so dass Sie geben nicht nur kann ^und @eine Zeile in in dem obigen Befehl.

Dieser Befehl entfernt alle ^@.

phresus
quelle
4
Bin nur über einen verwandten Link auf diese Frage / Antwort gestoßen: Dies ist eigentlich ein schlechter Rat und wird nur in sehr wenigen Fällen richtig funktionieren. Es ist besser, die Kodierung zu ändern, als Null-Bytes zu entfernen. Wenn Sie die Nullbytes entfernen, haben Sie möglicherweise noch andere Multibyte-Zeichen, die als Müll angezeigt werden.
Mario
@Mario könntest du uns mehr über die Kodierungsänderung erzählen? Hat das etwas mit der Antwort von jrb zu tun?
George
Siehe die Antwort von rpyzh weiter unten. Zeigt das Laden der Datei unter Verwendung der richtigen Kodierung sowie das Speichern mit einer anderen Kodierung an (obwohl die Antwort möglicherweise weitere Erklärungen benötigt). Die letzte Notiz von Jrb reicht aus, wenn Sie sie nur lesen möchten, aber nicht, wenn Sie sie ohne die Null-Bytes mit einer anderen Codierung speichern möchten.
Mario
50

Ich glaube nicht, dass Ihre Dateien beschädigt sind. Ihre Beispielzeile sieht so aus, als ob sie normalen Text mit Null-Bytes zwischen den einzelnen Zeichen enthält. Dies deutet darauf hin, dass es sich um eine Textdatei handelt, die in UTF-16 codiert wurde, aber die Markierung für die Bytereihenfolge am Anfang der Datei fehlt. Siehe http://en.wikipedia.org/wiki/Byte-order_mark

Angenommen, ich öffne Notepad, tippe das Wort 'Dateiname' und speichere es als Unicode-Big-Endian. Ein Hex-Dump dieser Datei sieht folgendermaßen aus:

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

Wenn ich diese Datei in Vim öffne, sieht es gut aus - die 'fe ff' Bytes teilen Vim mit, wie die Datei codiert ist. Nehmen wir nun an, ich erstelle eine Datei, die genau die gleiche Folge von Bytes enthält, jedoch ohne das führende 'fe ff'. Vim fügt ^ @ (oder <00>, abhängig von Ihrer Konfiguration) anstelle der Null-Bytes ein. Notepad fügt Leerzeichen ein.

Anstatt also die Nullen zu entfernen, sollten Sie wirklich versuchen, Vim dazu zu bringen, die Datei richtig zu interpretieren. Sie können Vim veranlassen, die Datei mit der richtigen Codierung mit dem folgenden Befehl neu zu laden:

:e ++enc=utf16

jrb
quelle
Ja, der letzte Befehl hat vim veranlasst, die Datei korrekt zu interpretieren, die Nullbytes werden jedoch nicht entfernt.
mrt181
6
Um sie zu entfernen, wählen Sie eine andere Kodierung und speichern Sie die Datei erneut:: setze fenc = utf-8
scy
35

Dies funktionierte tatsächlich für mich in vim:

:%s/\%x00//g
jriggins
quelle
5
Dies funktioniert mit substitute (), Ctl-VCtl-Shift-2 jedoch nicht.
Dsummersl
Das gleiche Problem für mich, ich konnte <Ctrl-V><Ctrl-2>(wie auch das mit <Ctrl-Shift-2>) nicht arbeiten, aber das hat funktioniert.
Jeff Bridgman
5
Das funktioniert bei mir unter Linux. '00' ist der ASCII-Hexadezimalwert, den Sie für jedes Zeichen in vim finden können, indem Sie den Cursor darüber platzieren und 'ga' (denken Sie an "get ascii") im Befehlsmodus oder: as /: ascii in der Befehlszeile eingeben .wikia.com / wiki /…
Casey Jones
^ Vx00 funktioniert auch. Sie können mit ^ VuXXXX auch einen 16-Bit-Unicode eingeben. Ich habe \% uXXXX bei einer Suche versucht und das hat auch funktioniert.
Edward Falk
Du wirst bis ans Ende der Zeit mein geliebter Mann sein. Aus tiefstem Herzen ... Danke!
Gonzalo Cao
12

Dieses 'Symbol' steht für ein NULL-Zeichen mit dem ASCII-Wert 000.

Es ist schwierig, mit vim zu entfernen, versuchen Sie es

tr -d '\000' < file1 > file2
Pavium
quelle
7

Wie andere angemerkt haben, sind dies Null-Bytes (ASCII 00). Unter Linux können Sie ASCII-Werte in vim eingeben, indem Sie Strg-V gefolgt vom dreistelligen Oktalwert eines beliebigen Zeichens drücken. Verwenden Sie zum Ersetzen aller Nullbytes Folgendes:

    :%s/Ctrl-V000//g

(ohne Leerzeichen).

Ebenso können Sie nach Nullen suchen mit:

    /Ctrl-V000

In beiden Fällen werden die Nullen bei der Eingabe nicht angezeigt, nach Eingabe aller drei wird sie jedoch angezeigt ^@. Auf den Farbterminals wird blau angezeigt, um anzuzeigen, dass es sich um ein Steuerzeichen handelt.

TheAmigo
quelle
6

FWIW, in meinem Fall musste ich vim auf cygwin verwenden, um eine auf einem Mac erstellte Textdatei zu bearbeiten. Die akzeptierte Lösung hat bei mir nicht funktioniert, war aber nah. Laut der Vim-Wiki-Seite zum Arbeiten mit Unicode gibt es einen Unterschied zwischen der Big-Endian- und der Little-Endian-Version des BOM-Bytes. Daher musste ich ausdrücklich festlegen vim, dass eine Little Endian-Version der Stücklistencodierung verwendet werden soll.

Erst nach Auswahl der richtigen Codierung habe ich das Dateiformat (Zeilenenden) in konvertiert, dosdamit ich die Datei im Windows-Editor bearbeiten konnte. Der Versuch, das Dateiformat zurückzusetzen, bevor die Codierung angegeben wurde, machte mir Sorgen. Hier ist die vollständige Liste der Befehle, die ich verwendet habe:

:e ++enc=utf16le
:w!
:e ++ff=mac
:setlocal ff=dos
:wq
rpyzh
quelle
Wertvolle Infos. In meinem Fall war es die Endianität des Stücklistenbytes.
Andre Albuquerque
3

Die akzeptierte Lösung hat bei mir nicht funktioniert. trStattdessen habe ich vim die Datei durchgeleitet:

:%!tr -d '\000'

Dies funktioniert auch im visuellen Modus (nur tippen :!tr -d '\000') oder in einer Reihe von Zeilen:

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

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

^@ Kein schlechtes Zeichen, wenn Sie eine ordnungsgemäße Codierung verwenden, aber wenn Sie entfernen möchten, versuchen Sie Folgendes:

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

In Ihren Beispieldaten steht das Zeichen ^ M

Um Ihre Datei vor der Verarbeitung in das Unix / Linux-Format zu konvertieren, versuchen Sie Folgendes:

dos2unix filename - Rhel und andere

dos2ux filename [newfilename] - HP-UX

user490343
quelle
1

Zusätzlich zur Antwort von @ jrb wird in Vim die Zeichenkodierung der Datei anhand der Option fileencodings ermittelt. (Beachten Sie das 's' am Ende der Dateikodierungen)

Dh unter Windows ist der Standardwert für die fileencodingsOption ucs-bom, was bedeutet:

Überprüfen Sie, ob am Anfang der Datei eine Stückliste vorhanden ist.

Wenn Stückliste vorhanden ist, lesen Sie die Zeichenkodierung der Datei aus der Stückliste.

Wenn keine Stückliste vorhanden ist (und dies in diesem Fall auch bedeuten würde, dass alle in der fileencodingsOption angegebenen Zeichenkodierungen nicht übereinstimmen), lesen Sie die Datei mit der in der encodingOption angegebenen Zeichenkodierung . Die Standard - Zeichencodierung für die encodingOption ist: latin1. Da latin1es sich nun um die Zeichencodierung mit einer Länge von einem Byte handelt , sind alle Bytes in der Datei gültige latin1Zeichen (auch das NulZeichen ^@, das Sie sehen *).

* - ist eigentlich ^@das Newline-Zeichen im Puffertext des Vim, nicht das Nul-Zeichen.

Die richtige Art, die Datei zu lesen, besteht darin, die Zeichencodierung manuell als UTF-16 anzugeben (da UTF-16 in diesem Fall die richtige Zeichencodierung ist).

colemik
quelle