J'essaie d'imprimer deux chaînes séparées par un TAB. J'ai essayé:
echo -e 'foo\tbar'
printf '%s\t%s\n' foo bar
Tous deux impriment:
foo bar
Où l'espace entre les deux est en fait de 5 espaces (selon la sélection de la sortie avec la souris dans Putty).
J'ai également essayé d'utiliser CTRL + V et d'appuyer sur TAB lors de la frappe de la commande, avec le même résultat.
Quelle est la bonne façon de forcer l’impression de l’onglet en tant qu’onglet, afin de pouvoir sélectionner la sortie et la copier ailleurs, avec des onglets?
Et la question secondaire: pourquoi bash étend-il les onglets dans les espaces?
Mise à jour : Apparemment, c'est un problème de Putty: /superuser/656838/how-to-make-putty-display-tabs-within-a-file-instead-of-changing-them-to -les espaces
bash
putty
whitespace
tabs
Asu
la source
la source
printf '%s\\t%s\n' foo bar
foo\tbar
...$'\t'
comme tabulateur. Ainsi, vous pouvez toujours concaténer des chaînes comme celle-ci - par exemple comme affectation:v='This is'$'\t''a test'
Et l'imprimer littéralement, par exempleprintf '%s' "$v"
Réponses:
Comme ilkkachu l'a dit, ce n'est pas un problème avec bash, mais avec l'émulateur de terminal qui convertit les tabulations en espaces en sortie.
La vérification de différents terminaux, putty, xterm et konsole convertit les onglets en espaces, contrairement à urxvt et gnome-terminal. Une autre solution consiste donc à changer de terminal.
la source
stty tab3
.Non ce n'est pas. Pas dans la sortie de
echo
ouprintf
.C'est un problème différent. Il ne s'agit pas du shell mais de l'émulateur de terminal, qui convertit les tabulations en espaces en sortie. Beaucoup, mais pas tous.
Il peut être plus facile de rediriger la sortie avec des tabulations vers un fichier et de la copier à partir de là, ou d'utiliser
unexpand
sur la sortie pour convertir des espaces en tabulations. (Bien qu'il ne puisse pas non plus savoir quels espaces étaient des onglets pour commencer, et les convertira tous en onglets, si possible.) Cela dépendra bien sûr de ce que vous devez faire exactement avec la sortie.la source
Dans
printf '%s\t%s\n' foo bar
,printf
fait la sortiefoo<TAB>bar<LF>
.f
,o
,b
,a
Etr
sont des caractères graphiques à simple largeur.À la réception de ces caractères, le terminal affichera un glyphe correspondant et déplacera le curseur d'une colonne vers la droite, à moins qu'il n'ait déjà atteint le bord droit de l'écran (papier dans les télé-machines à écrire d'origine)), auquel cas il peut alimenter une ligne et revenir au bord gauche de l'écran (envelopper) ou simplement jeter le caractère en fonction du terminal et de la façon dont il a été configuré.
<Tab>
et<LF>
sont deux caractères de contrôle .<LF>
(aka newline) est le délimiteur de ligne dans le texte Unix, mais pour les terminaux, il alimente simplement une ligne (déplacez le curseur d'une position vers le bas). Ainsi, le pilote de terminal dans le noyau le traduira en fait<CR>
(retour au bord gauche de l'écran),<LF>
(curseur vers le bas) (stty onlcr
généralement activé par défaut).<Tab>
indique au terminal de déplacer le curseur vers le taquet de tabulation suivant (qui sur la plupart des terminaux sont distants de 8 positions par défaut mais peut également être configuré pour être défini n'importe où) sans remplir l'espace avec des blancs.Donc, si ces caractères sont envoyés à un terminal avec des tabulations toutes les 8 colonnes alors que le curseur est au début d'une ligne vide, cela se traduira par:
imprimé sur l'écran à cette ligne. S'ils sont envoyés alors que le curseur est en troisième position dans une ligne qui contient
xxxxyyyyzzzz
, cela se traduira par:Sur les terminaux qui ne prennent pas en charge la tabulation, le pilote de terminal peut être configuré pour traduire ces onglets en séquences d'espaces. (
stty tab3
).Le caractère SPC, dans les télé-machines à écrire d'origine, déplacerait le curseur vers la droite, tandis que backspace (
\b
) le déplacerait vers la gauche. Désormais, dans les terminaux modernes, SPC se déplace vers la droite et efface également (écrit un caractère d'espace comme vous vous en doutez). Le pendentif\b
devait donc être quelque chose de plus récent que ASCII. Sur la plupart des terminaux, il est en fait une séquence de caractères:<Esc>
,[
,C
.Il existe plus de séquences d'échappement pour déplacer les
n
personnages vers la gauche, la droite, le haut, le bas ou à n'importe quelle position sur l'écran. Il existe d'autres séquences d'échappement pour effacer (remplir avec des blancs) des parties de lignes ou régions de l'écran, etc.Ces séquences sont généralement utilisés par des applications visuelles comme
vi
,lynx
,mutt
,dialog
où le texte est écrit à des positions arbitraires sur l'écran.Maintenant, tous les émulateurs de terminaux X11 et quelques autres non-X11 comme GNU
screen
vous permettent de sélectionner des zones de l'écran pour copier-coller. Lorsque vous sélectionnez une partie de ce que vous voyez dans l'vi
éditeur, vous ne voulez pas copier toutes les séquences d'échappement qui ont été utilisées pour produire cette sortie. Vous souhaitez sélectionner le texte que vous y voyez.Par exemple, si vous exécutez:
Ce qui simule une session d'éditeur où vous entrez
abC
, revenez au début, remplacezab
parAC
,C
avecB
, passez à la tabulation suivante, puis une autre colonne à droite, puis deux colonnes à gauche, puis entrezD
.Tu vois:
Autrement dit,
ABC
un écart de 4 colonnes etD
.Si vous sélectionnez cela avec la souris dans
xterm
ouputty
, ils stockeront dans la sélectionABC
, 4 caractères d'espacement etD
nonabC<CR>AC<BS>B<Tab><Esc>[C<BS><BS>D
.Ce qui finit dans la sélection est ce qui a été envoyé par le
printf
post-traitement et l'émulateur de terminal, mais post-traité.Pour d'autres types de transformation, voir le
<U+0065><U+0301>
(e
suivi d'un accent aigu combiné) changé en<U+00E9>
(é
la forme pré-composée) parxterm
.Ou
echo abc
qui finit par être traduitABC
par le pilote du terminal avant d'être envoyé au terminal après astty olcuc
.Maintenant,
<Tab>
comme<LF>
est l'un de ces quelques caractères de contrôle qui se trouvent parfois dans les fichiers texte (également<CR>
dans les fichiers texte MSDOS et parfois<FF>
pour les sauts de page).Certains émulateurs de terminaux choisissent donc de les copier lorsque cela est possible dans les tampons de copier-coller pour les conserver (ce n'est généralement pas le cas,
<CR>
ni<LF>
si).Par exemple, dans les terminaux basés sur VTE comme
gnome-terminal
, vous pouvez voir que, lorsque vous sélectionnez la sortie deprintf 'a\tb\n'
sur une ligne vide,gnome-terminal
stockea\tb
en fait dans la sélection X11 au lieu dea
, 7 espaces etb
.Mais pour la sortie
printf 'a\t\bb\n'
, il stockea
, 6 places etb
, etprintf 'a\r\tb\n'
,a
, 7 places etb
.Il y a d'autres cas où les terminaux essaieront de copier l'entrée réelle, comme lorsque vous sélectionnez deux lignes après l'exécution
printf 'a \nb\n'
où cet espace de fin invisible sera préservé. Ou lorsque la sélection de deux lignes n'inclut pas de caractère LF lorsque les deux lignes résultent d'un habillage à la marge de droite.Maintenant, si vous voulez stocker la sortie de
printf
dans le CLIPBOARDX11
select, le mieux est de le faire directement comme avec:Notez que lorsque vous collez cela dans
xterm
ou la plupart des autres terminaux,xterm
remplace réellement cela\n
par\r
car c'est le caractèrexterm
envoyé lorsque vous appuyez sur Enter(et le pilote de terminal peut le traduire à nouveau\n
).la source
X11
c'est ce qui gère la sélection copier-coller dans les émulateurs de terminaux commexterm
ouputty
sur Unix. D'autres émulateurs de terminaux peuvent avoir leur propre mécanisme de copier-coller et des moyens de stocker du contenu arbitraire, comme les commandesreadbuf
etregister
dans l'écran GNU.