Le caractère ASCII du séparateur d'unités (ASCII 31, octal 37) est visible dans Vim sous la forme d'un ^_
. Mais si j'imprime le même fichier sur le terminal, le caractère est invisible. Cela provoque le blocage des champs d'une ligne:
# In Vim and less:
first field^_second field^_last field
# cat the same file to terminal:
cat delim.txt
first fieldsecond fieldlast field
# print 2nd field with awk
cat delim.txt | awk 'BEGIN {FS = "\037"} {print $2}'
second field
Je suppose que je peux rendre le séparateur d'unités visible avec cat -v:
cat -v delim.txt
first field^_second field^_last field
Mais c'est assez lourd. Pourquoi le séparateur d'unités n'a-t-il pas une représentation visible lorsqu'il est imprimé sur stdout dans le shell Bash? Je ne peux même pas copier et coller correctement la sortie du shell; le séparateur d'unités se perd dans le processus.
Réponses:
Le caractère séparateur d'unité (
US
), également appeléIS1
, se trouve dans lacntrl
classe de caractères et n'est pas dans laprint
classe de caractères. Il s'agit d'un caractère de contrôle destiné à organiser le texte en groupes, pour les programmes conçus pour utiliser ces informations . En général, les caractères non imprimables vont probablement être interprétés et rendus différemment dans différents programmes ou environnements.La raison pour laquelle vous le voyez représenté comme
^_
dans Vim est que Vim est un éditeur interactif. Il peut restituer librement les caractères non imprimables comme il le souhaite, tant que le caractère binaire correct est écrit sur le disque.Vous ne pouvez pas obtenir le même comportement dans le shell car les programmes shell Unix sont écrits pour fonctionner et se transmettre du texte brut. Lorsque vous
cat
un fichier, le texte qui est écrit sur le terminal doit être ce qui est réellement dans le fichier.Cela laisse donc au terminal le soin d'interpréter le personnage. Et il se trouve que certains émulateurs font rendre le
US
caractère différemment des autres. Dansgnome-terminal
(ou toutvte
terminal basé sur), le caractère sera rendu sous la forme d'une boîte contenant le code hexadécimal001F
. Dansxterm
ourxvt
, le personnage est en effet invisible.la source
US
c'est totalement invisible. Lorsque j'insère ce caractère dans un terminal avecCtrl+/
(confirmé via<C-v><C-/>
), il supprime une quantité imprévisible de texte sur la ligne. Je ne comprends pas bien son comportement, mais il semble avoir principalement une sorte d'effet "onglet inversé" où au lieu d'insérer un certain nombre d'espaces, il supprime un certain nombre de caractères, mais parfois il insère au hasard du texte, donc c'est déroutant .Le séparateur d'unités est dans la plage ASCII des caractères de contrôle et n'a donc pas (ou ne devrait généralement pas) de représentation visuelle.
Vim et certains autres éditeurs les affichent, vous pouvez donc les modifier. Comme vous l'avez remarqué, l'
cat -v
affiche également. La page de manuel montre, c'est-à--v
dire la forme abrégée de--show-nonprinting
, ce qui oblige à remplacer les caractères non imprimables par une représentation imprimable, qui n'est pas le contenu original du fichier et pourrait donc causer des problèmes, si la sortie est en fait vers un autre programme .La représentation que vous voyez indique déjà qu'il s'agit d'un caractère de contrôle: un caractère précédé d'un
^
est une notation courante pour Ctrl+ le caractère, qui est la combinaison de touches qui produit ce caractère dans un terminal. Ctrl+ _vous permettra par exemple de saisir le séparateur d'unités dans vim. Mais un autre éditeur ou un visualiseur GUI peut afficher le code hexadécimal, un espace réservé ou quelque chose de complètement différent.Comme votre terminal n'imprime pas les caractères de contrôle, il n'est pas non plus copié lors de la sélection du texte (les caractères blancs comme la nouvelle ligne et tabulation sont une exception ici, qui sont aussi des caractères de contrôle). Un autre exemple de caractères de contrôle dans le terminal qui sont généralement ignorés lors de la copie sont les codes de couleur, qui sont un
ESC
caractère suivi du code de coloration du texte.Donc, pour afficher les caractères sur votre terminal, il n'y a pas d'autre moyen que d'utiliser un programme qui remplace le séparateur d'unités par un caractère imprimable.
la source
Un peu en marge des autres (très bonnes) réponses, si vous souhaitez modifier uniquement le caractère de contrôle
^_
lors de l'affichage du contenu du fichier, vous pouvez le translitérer à l'aide de l'tr
utilitaire (et un peu de syntaxe compatible bash) :Si vous devez remplacer ce caractère de contrôle par sa forme "étendue", vous aurez besoin à la
sed
place:Veuillez noter la syntaxe
$'\cX'
: cette syntaxe informe votre (shell compatible bash) de remplacer le caractère de contrôle correspondant. Voir wikipedia pour une liste d'alias de caractères de contrôle utilisant la "notation caret". Si vous n'aimez pas cette syntaxe, vous préférerez peut-être utiliser la notation octale$'\037'
ou hexadécimale à la$'\x1f'
place.la source