Comment supprimer ce symbole “^ @” avec vim?

59

J'ai des fichiers qui sont corrompus avec ce symbole:

^ @

Cela ne fait pas partie de la ficelle; ce n'est pas consultable. Comment remplacer ce symbole par rien ou comment supprimer ce symbole?

Voici un exemple de ligne d'un fichier:

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

Réponses:

51

Tu pourrais essayer:

  • %s/<CTRL-2>//g (sur des PC réguliers)

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

<CTRL-2>signifie tout d’abord appuyer CTRLsur les ordinateurs ordinaires, en les maintenant enfoncés, frapper 2, relâcher CTRL.

et <CTRL-SHIFT-2>signifie d'abord appuyer sur le controlPC Mac, en le maintenant, appuyer sur shiftle PC Mac, en maintenant, presser 2, relâcher controlet shift.

Enfin, les deux commandes devraient %s/^@//gapparaître à l’écran. ^@signifie un seul caractère (un octet NULL, qui ne pourrait pas être affiché autrement), non ^suivi de @, vous ne pouvez donc pas simplement taper ^et @dans une ligne dans la commande ci-dessus.

Cette commande supprime tous les ^@.

phresus
la source
4
Je suis tombé par hasard sur cette question / réponse via un lien connexe: c’est en fait un mauvais conseil qui ne fonctionnera correctement que dans très peu de cas. Il est préférable de modifier le codage plutôt que de supprimer les octets nuls. Si vous supprimez les octets nuls, il est possible que d'autres caractères multi-octets apparaissent toujours comme des ordures.
Mario
@ Mario pouvez-vous nous en dire plus sur le changement d'encodage? Est-ce quelque chose lié à la réponse de Jrb ci-dessous?
George
Voir la réponse de rpyzh plus bas. Affiche le chargement du fichier en utilisant le bon codage et l’enregistrement avec un autre (bien que la réponse puisse nécessiter des explications supplémentaires). La dernière note de Jrb est suffisante si vous voulez seulement la lire, mais pas si vous voulez la sauvegarder sans octets nuls en utilisant un autre encodage.
Mario
50

Je ne pense pas que vos fichiers sont corrompus. Votre exemple de ligne ressemble à du texte normal avec des octets nuls entre chaque caractère. Cela suggère qu'il s'agit d'un fichier texte encodé au format UTF-16 mais que la marque d'ordre des octets est manquante au début du fichier. Voir http://en.wikipedia.org/wiki/Byte-order_mark

Supposons que j'ouvre le Bloc-notes, tapez le mot 'nomfichier' et l'enregistre en tant que Big-endian Unicode. Un vidage hexadécimal de ce fichier ressemble à ceci:

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

Si j'ouvre ce fichier dans Vim, tout se passe bien: les octets 'fe ff' indiquent à Vim comment le fichier est codé. Supposons maintenant que je crée un fichier contenant exactement la même séquence d'octets, mais sans le 'fe ff' initial. Vim insère ^ @ (ou <00>, selon votre configuration), à la place des octets nuls; Le bloc-notes insère des espaces.

Donc, plutôt que de supprimer les valeurs NULL, vous devriez vraiment chercher à ce que Vim interprète correctement le fichier. Vous pouvez faire en sorte que Vim recharge le fichier avec le bon codage avec la commande:

:e ++enc=utf16

Jrb
la source
Oui, la dernière commande faite par vim interprète le fichier correctement mais ne supprime pas les nullbytes.
mrt181
6
Pour les supprimer, choisissez un autre encodage et enregistrez le fichier à nouveau:: set fenc = utf-8
scy
35

Cela a réellement fonctionné pour moi au sein de vim:

:%s/\%x00//g
Jriggins
la source
5
cela fonctionne avec substitute (), mais pas Ctl-VCtl-Shift-2.
dsummersl
Même problème pour moi, je ne pouvais pas obtenir <Ctrl-V><Ctrl-2>(ainsi que celui avec <Ctrl-Shift-2>) de travailler non plus, mais cela a fonctionné.
Jeff B
5
Cela fonctionne pour moi Linux. "00" est la valeur hexadécimale ASCII que vous pouvez trouver pour n'importe quel caractère de vim en plaçant le curseur dessus et en tapant "ga" (pensez à "get ascii") en mode commande ou: comme /: ascii sur la ligne de commande. Vim .wikia.com / wiki /…
Casey Jones
^ Vx00 fonctionne également. Vous pouvez également entrer en unicode 16 bits avec ^ VuXXXX. J'ai essayé \% uXXXX dans une recherche et cela a également fonctionné.
Edward Falk
Tu seras mon homme bien-aimé jusqu'à la fin des temps. Du fond de mon coeur ... merci!
Gonzalo Cao
12

Ce 'symbole' représente un caractère NULL, avec la valeur ASCII 000.

C'est difficile à enlever avec vim, essayez

tr -d '\000' < file1 > file2
pavium
la source
7

Comme d'autres l'ont noté, il s'agit d'octets nuls (ASCII 00). Sous Linux, pour entrer des valeurs ASCII dans vim, appuyez sur Ctrl-V, suivi de la valeur octale à 3 chiffres de n’importe quel caractère. Pour remplacer tous les octets nuls, utilisez:

    :%s/Ctrl-V000//g

(sans espaces).

De même, vous pouvez rechercher des valeurs NULL avec:

    /Ctrl-V000

Dans les deux cas, les zéros ne seront pas affichés au fur et à mesure que vous les tapez, mais après avoir entré les trois, ils s'afficheront ^@. Sur les terminaux de couleur, il sera indiqué en bleu pour indiquer qu'il s'agit d'un caractère de contrôle.

TheAmigo
la source
6

FWIW, dans mon cas, j’ai dû utiliser vim on cygwin pour éditer un fichier texte créé sur un mac. La solution acceptée ne fonctionnait pas pour moi, mais était proche. Selon la page wiki de Vim sur l'utilisation de Unicode , il existe une différence entre les versions Big Endian et Little Endian de l'octet de nomenclature. Donc, je devais explicitement dire vimd'utiliser une version Little Endian de l'encodage de la nomenclature.

Ce n’est qu’après avoir choisi le bon encodage que j’ai converti le format de fichier (fins de ligne) dosafin de pouvoir éditer le fichier dans l’éditeur Windows. Essayer de définir la réinitialisation du format de fichier avant de spécifier l'encodage m'a donné du chagrin. Voici la liste complète des commandes que j'ai utilisées:

:e ++enc=utf16le
:w!
:e ++ff=mac
:setlocal ff=dos
:wq
rpyzh
la source
Infos précieuses. Dans mon cas, c’était la finalité de l’octet de nomenclature.
Andre Albuquerque
3

La solution acceptée ne fonctionnait pas pour moi. J'ai fait passer le fichier par vim à la trplace:

:%!tr -d '\000'

Cela fonctionnerait également bien avec le mode visuel (il suffit de taper :!tr -d '\000') ou sur une plage de lignes:

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

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

^@ Ce n'est pas un mauvais personnage si vous utilisez un encodage approprié, mais si vous voulez le supprimer, essayez:

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

^ M caractère est là dans vos données d'exemple

Pour convertir votre fichier au format Unix / Linux avant tout traitement, essayez:

dos2unix filename - rhel et autres

dos2ux filename [newfilename] - HP-UX

utilisateur490343
la source
1

En plus de la réponse de @ jrb, dans Vim, le codage de caractères du fichier est détecté en fonction de l'option fileencodings. (notez le 's' à la fin du codage de fichier)

C'est-à-dire que, sous Windows, la valeur par défaut de l' fileencodingsoption est ucs-bom:

vérifie si la nomenclature existe au début du fichier.

Si la nomenclature existe, «lisez le codage de caractères du fichier en dehors de la nomenclature».

Si la nomenclature n'existe pas (et dans ce cas, cela signifierait également que tous les codages de caractères spécifiés dans l' fileencodingsoption ne correspondent pas), lisez le fichier avec le codage de caractères spécifié dans l' encodingoption. Le caractère encodage par défaut pour l' encodingoption est: latin1. Maintenant, comme il latin1s’agit du codage de caractères d’ une longueur d’ octets , tous les octets du fichier sont des latin1caractères valides (même le Nulcaractère ^@que vous voyez *).

* - en fait, ^@est le caractère de nouvelle ligne dans le texte du tampon de Vim, pas le caractère Nul.

La bonne façon de lire le fichier est de spécifier manuellement le codage de caractères au format UTF-16 (car il semble que UTF-16 est le codage de caractères approprié dans ce cas).

Colemik
la source