Identification et suppression des caractères nuls sous UNIX

98

J'ai un fichier texte contenant des caractères nuls indésirables (ASCII NUL, \0). Lorsque j'essaye de l'afficher dans, vije vois des ^@symboles entrelacés dans du texte normal. Comment puis-je:

  1. Identifiez les lignes du fichier contenant des caractères nuls? J'ai essayé grepping pour \0et \x0, mais cela n'a pas fonctionné.

  2. Supprimer les caractères nuls? L'exécution stringssur le fichier l'a nettoyé, mais je me demande simplement si c'est la meilleure façon?

dogbane
la source
1
Ce genre de question appartient probablement à SuperUser.com
Olivier Lalonde
2
En fait, cette question est sur superuser.com: superuser.com/questions/75130/how-to-remove-ths-symbol-with-vim
jrb

Réponses:

130

J'utiliserais tr:

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

Si vous vous demandez si la redirection d'entrée au milieu des arguments de commande fonctionne, c'est le cas. La plupart des shells reconnaîtront et faire face à la redirection d' E / S ( <, >...) partout dans la ligne de commande, en fait.

Pointu
la source
et un "diff fichier-avec-nulls fichier-sans-nulls" devrait me montrer quelles lignes avaient des caractères nuls? Cela rapporte beaucoup plus que prévu.
dogbane
10
En fait, je pense que cela devrait l'être, tr -d '\000' < file-with-nulls > file-without-nullscar cela <fait partie de la fonctionnalité du tube shell et non tr.
Mikael S
9
La plupart des shells reconnaîtront et traiteront <ou> n'importe où dans la chaîne d'argument, en fait. M'a surpris aussi.
pra
1
+1 Pour l'utilisation de la redirection d'entrée au lieu de cat |. Une solution fine et propre qui a résolu mon problème.
Krzysztof Jabłoński
4
@Pointy '\ 000' est utilisé à la place de '\ 0' dans la spécification de groupe ouvert POSIX pour tr. C'est une bonne raison de le préférer
Harold Fischer
67

Utilisez la commande sed suivante pour supprimer les caractères nuls dans un fichier.

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

cette solution édite le fichier en place, ce qui est important si le fichier est toujours utilisé. passer -i'ext 'crée une sauvegarde du fichier original avec le suffixe' ext 'ajouté.

rekha_sri
la source
6
Remarque: dans FreeBSD (et je crois aussi Mac OS X), sed -i nécessite une extension dans l'argument suivant, mais il peut être vide. Dans ces systèmes, ajoutez un '', comme dans: sed -i '' 's/\x0//g "$FILE".
Tim Čas
1
C'est un ordre de grandeur plus rapide que trpour moi
diachedelic
Pour moi, en utilisant Git pour Windows et $ sed --version-> sed (GNU sed) 4.7, j'ai dû utiliser l'invocation suivante pour obtenir un fichier de sauvegarde appelé example.csv.bak:sed -i.bak 's/\x0//g' example.csv
Andrew Keeton le
1
@ TimČas vous l'avez très bien fait, j'ai manqué de peu un 'donc ça devrait être sed -i' '' s / \ x0 // g 'some_file.xml
Darko
@Darko C'est ce que j'ai fait. Oups.
Tim Čas
22

Un grand nombre de caractères NUL indésirables, disons un tous les autres octets, indique que le fichier est encodé en UTF-16 et que vous devez l'utiliser iconvpour le convertir en UTF-8.

Ignacio Vazquez-Abrams
la source
1
J'ai manqué d'espace disque pendant la journalisation de mon application. Cela aboutit à ces caractères.
dogbane
Par exemple, il fonctionne à l' aide de cette commande: iconv -f UTF-16 -t UTF-8 file.
djule5 le
7

J'ai découvert ce qui suit, qui affiche quelles lignes, le cas échéant, ont des caractères nuls:

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

De plus, un vidage octal peut vous dire s'il y a des valeurs nulles:

od file-with-nulls | grep ' 000'
dogbane
la source
5

Si les lignes du fichier se terminent par \ r \ n \ 000 alors ce qui fonctionne est de supprimer le \ n \ 000 puis de remplacer \ r par \ n.

tr -d '\n\000' <infile | tr '\r' '\n' >outfile
wwmbes
la source
PS. Si vous vous trouvez dans un shell Windows DOS, vous pouvez obtenir les versions GNU / win32 des commandes Unix sur Sourceforge.net. Je les utilise tout le temps. Consultez "od" la commande octal dump pour analyser le contenu d'un fichier ...
wwmbes
2

Voici un exemple de suppression des caractères NULL à l'aide de ex(in-place):

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

et pour plusieurs fichiers:

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

Pour la récursivité, vous pouvez utiliser l' option de globbing **/*.txt (si elle est prise en charge par votre shell).

Utile pour les scripts car sed et son -iparamètre est une extension BSD non standard.

Voir aussi: Comment vérifier si le fichier est un fichier binaire et lire tous les fichiers qui ne le sont pas?

Kenorb
la source
1

J'ai utilisé:

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

pour se débarrasser des zéros dans le fichier.

logisec
la source
0

J'ai fait face à la même erreur avec:

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

J'ai résolu le problème en changeant l'encodage en utf-16

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