Identifizieren und Entfernen von Nullzeichen unter UNIX

98

Ich habe eine Textdatei mit unerwünschten Nullzeichen (ASCII NUL, \0). Wenn ich versuche, es in anzuzeigen, visehe ich ^@Symbole, die in normalem Text verschachtelt sind. Wie kann ich:

  1. Identifizieren Sie, welche Zeilen in der Datei Nullzeichen enthalten? Ich habe versucht, nach \0und zu greifen \x0, aber das hat nicht funktioniert.

  2. Nullzeichen entfernen? Laufen stringsauf der Datei reinigte ihn, aber ich frage mich nur , wenn dies der beste Weg?

Dogbane
quelle
1
Diese Art von Frage gehört wahrscheinlich zu SuperUser.com
Olivier Lalonde
2
In der Tat ist diese Frage auf superuser.com: superuser.com/questions/75130/how-to-remove-ths-symbol-with-vim
wk

Antworten:

130

Ich würde verwenden tr:

tr < file-with-nulls -d '\000' > file-without-nulls

Wenn Sie sich fragen, ob die Umleitung von Eingaben in der Mitte der Befehlsargumente funktioniert, ist dies der Fall. Die meisten Schalen werden erkennen , und befassen sich mit E / A - Umleitung ( <, >, ...) überall in der Befehlszeile, eigentlich.

Spitze
quelle
und eine "diff-Datei mit Nullen Datei ohne Nullen" sollte mir zeigen, welche Zeilen Nullzeichen hatten? Es bringt viel mehr als erwartet zurück.
Dogbane
10
Eigentlich glaube ich, dass es so sein sollte, tr -d '\000' < file-with-nulls > file-without-nullsda <es Teil der Shell-Pipe-Funktionalität ist und nicht tr.
Mikael S
9
Die meisten Shells erkennen <oder> tatsächlich irgendwo in der Argumentzeichenfolge und behandeln sie. Hat mich auch überrascht.
Pra
1
+1 Für die Verwendung der Eingabeumleitung anstelle von cat |. Eine gute, saubere Lösung, die mein Problem gelöst hat.
Krzysztof Jabłoński
4
@Pointy '\ 000' wird anstelle von '\ 0' in der POSIX-Opengroup-Spezifikation für tr verwendet. Das ist ein guter Grund, es vorzuziehen
Harold Fischer
67

Verwenden Sie den folgenden Befehl sed, um die Nullzeichen in einer Datei zu entfernen.

sed -i 's/\x0//g' null.txt

Diese Lösung bearbeitet die Datei an ihrem Platz. Dies ist wichtig, wenn die Datei noch verwendet wird. Durch Übergeben von -i'ext wird eine Sicherungskopie der Originaldatei mit dem Suffix 'ext' erstellt.

rekha_sri
quelle
6
Hinweis: In FreeBSD (und ich glaube auch in Mac OS X) ist im nächsten Argument eine Erweiterung sed -i erforderlich , die jedoch möglicherweise leer ist. Fügen Sie in diesen Systemen ein hinzu '', wie in : sed -i '' 's/\x0//g "$FILE".
Tim
1
Dies ist eine Größenordnung schneller als trfür mich
diachedelisch
Bei Verwendung von Git für Windows und $ sed --version-> sed (GNU sed) 4.7musste ich den folgenden Aufruf verwenden, um eine Sicherungsdatei mit dem Namen example.csv.baksed -i.bak 's/\x0//g' example.csv
abzurufen
1
@ TimČas du hast es großartig gemacht, habe gerade eines verpasst, also sollte es sed -i '' s / \ x0 // g 'some_file.xml sein
Darko
@ Darko Also habe ich. Hoppla.
Tim
22

Eine große Anzahl unerwünschter NUL-Zeichen, beispielsweise jedes zweite Byte, zeigt an, dass die Datei in UTF-16 codiert ist und dass Sie sie iconvzum Konvertieren in UTF-8 verwenden sollten.

Ignacio Vazquez-Abrams
quelle
1
Während der Protokollierung meiner Anwendung ging mir der Speicherplatz aus. Dies führt zu diesen Zeichen.
Dogbane
Zum Beispiel funktioniert es mit diesem Befehl : iconv -f UTF-16 -t UTF-8 file.
djule5
7

Ich habe Folgendes entdeckt, das ausgibt, welche Zeilen, falls vorhanden, Nullzeichen haben:

perl -ne '/\000/ and print;' file-with-nulls

Ein Oktal-Dump kann Ihnen auch sagen, ob es Nullen gibt:

od file-with-nulls | grep ' 000'
Dogbane
quelle
5

Wenn die Zeilen in der Datei mit \ r \ n \ 000 enden, müssen Sie die \ n \ 000 löschen und dann die \ r durch \ n ersetzen.

tr -d '\n\000' <infile | tr '\r' '\n' >outfile
wwmbes
quelle
PS. Wenn Sie sich in einer Windows-DOS-Shell befinden, können Sie die GNU / win32-Versionen von Unix-Befehlen von Sourceforge.net herunterladen. Ich benutze sie die ganze Zeit. Schauen Sie sich den oktalen Dump-Befehl "od" an, um zu analysieren, was in einer Datei enthalten ist ...
wwmbes
2

Hier ist ein Beispiel zum Entfernen von NULL-Zeichen mit ex(an Ort und Stelle):

ex -s +"%s/\%x00//g" -cwq nulls.txt

und für mehrere Dateien:

ex -s +'bufdo!%s/\%x00//g' -cxa *.txt

Für die Rekursivität können Sie die Globbing-Option verwenden **/*.txt (sofern diese von Ihrer Shell unterstützt wird).

Nützlich für Skripte seit sed und seine-i Parameter ist eine nicht standardmäßige BSD-Erweiterung.

Siehe auch: Wie überprüfe ich, ob die Datei eine Binärdatei ist, und lese alle Dateien, die es nicht sind?

Kenorb
quelle
1

Ich benutzte:

recode UTF-16..UTF-8 <filename>

Nullen in der Datei loswerden.

logisec
quelle
0

Ich hatte den gleichen Fehler mit:

import codecs as cd
f=cd.open(filePath,'r','ISO-8859-1')

Ich habe das Problem gelöst, indem ich die Codierung auf geändert habe utf-16

f=cd.open(filePath,'r','utf-16')
Ming Young
quelle