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?


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.


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é.


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.


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'

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

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?


1

J'ai utilisé:

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

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


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')
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.