In printf '%s\t%s\n' foo bar
, printf
genera output foo<TAB>bar<LF>
.
f
, o
, b
, a
E r
sono i caratteri grafici a singola larghezza.
Dopo aver ricevuto quei caratteri, il terminale visualizzerà un glifo corrispondente e sposta il cursore di una colonna a destra, a meno che non abbia già raggiunto il bordo destro dello schermo (carta nelle tele-macchine da scrivere originali)), nel qual caso può alimentare una linea e tornare al bordo sinistro dello schermo (a capo) o semplicemente scartare il personaggio a seconda del terminale e di come è stato configurato.
<Tab>
e <LF>
sono due personaggi di controllo . <LF>
(aka newline) è il delimitatore di riga nel testo Unix, ma per i terminali alimenta solo una linea (sposta il cursore di una posizione verso il basso). Quindi il driver del terminale nel kernel lo tradurrà effettivamente in <CR>
(torna al bordo sinistro dello schermo), <LF>
(cursore in basso) ( stty onlcr
generalmente acceso di default).
<Tab>
indica al terminale di spostare il cursore sul tab stop successivo (che sulla maggior parte dei terminali sono 8 posizioni distinte per impostazione predefinita, ma può anche essere configurato per essere impostato ovunque) senza riempire il vuoto con spazi vuoti.
Pertanto, se quei caratteri vengono inviati a un terminale con tabulazioni ogni 8 colonne mentre il cursore si trova all'inizio di una riga vuota, ciò comporterà:
foo bar
stampato sullo schermo su quella linea. Se vengono inviati mentre il cursore si trova in terza posizione in una riga che contiene xxxxyyyyzzzz
, ciò comporterà:
xxfooyyybarz
Sui terminali che non supportano la tabulazione, il driver del terminale può essere configurato per tradurre quelle schede in sequenze di spazi. ( stty tab3
).
Il carattere SPC, nelle macchine da scrivere originali, spostava il cursore a destra, mentre backspace ( \b
) lo spostava a sinistra. Ora nei terminali moderni, SPC si sposta a destra e cancella anche (scrive un carattere spaziale come ci si aspetterebbe). Quindi il pendente di \b
doveva essere qualcosa di più nuovo di ASCII. Sulla maggior parte dei terminali moderni, in realtà è una sequenza di caratteri: <Esc>
, [
, C
.
Esistono più sequenze di escape per spostare i n
personaggi a sinistra, a destra, in alto, in basso o in qualsiasi posizione sullo schermo. Esistono altre sequenze di escape per cancellare (riempire con spazi vuoti) parti di linee o aree dello schermo, ecc.
Tali sequenze sono tipicamente utilizzati per applicazioni visivi come vi
, lynx
, mutt
, dialog
in cui il testo è scritto in posizioni arbitrarie sullo schermo.
Ora, tutti gli emulatori di terminale X11 e alcuni altri non X11 come GNU screen
ti consentono di selezionare le aree dello schermo per il copia incolla. Quando selezioni una parte di ciò che vedi vi
nell'editor, non vuoi copiare tutte le sequenze di escape utilizzate per produrre quell'output. Vuoi selezionare il testo che vedi lì.
Ad esempio se esegui:
printf 'abC\rAC\bB\t\e[C\b\bD\n'
Il che simula una sessione dell'editor in cui si entra abC
, si torna all'inizio, si sostituisce ab
con AC
, C
con B
, si passa alla successiva tabulazione, quindi un'altra colonna a destra, quindi due colonne a sinistra, quindi si entra D
.
Vedi:
ABC D
Cioè ABC
, un gap di 4 colonne e D
.
Se lo selezioni con il mouse in xterm
o putty
, memorizzeranno nella selezione ABC
4 caratteri spaziali e D
non abC<CR>AC<BS>B<Tab><Esc>[C<BS><BS>D
.
Ciò che finisce nella selezione è ciò che è stato inviato printf
ma post-elaborato sia dal driver del terminale che dall'emulatore di terminale.
Per altri tipi di trasformazione, vedere <U+0065><U+0301>
( e
seguito da un accento acuto combinato) modificato in <U+00E9>
( é
la forma precomposta) da xterm
.
O echo abc
che finisce per essere tradotto ABC
dal driver del terminale prima di inviarlo al terminale dopo un stty olcuc
.
Ora, <Tab>
come <LF>
è uno di quei pochi caratteri di controllo che a volte si trovano effettivamente nei file di testo (anche <CR>
nei file di testo MSDOS e talvolta <FF>
per l'interruzione di pagina).
Quindi alcuni emulatori di terminali scelgono di copiarli quando possibile nei buffer di copia e incolla per preservarli (generalmente non è il caso <CR>
né il caso <LF>
).
Ad esempio, in terminali basati su VTE come gnome-terminal
, potresti vedere che, quando selezioni l'output printf 'a\tb\n'
su una riga vuota, in gnome-terminal
realtà memorizza a\tb
nella selezione X11 anziché a
7 spazi e b
.
Ma per l'output di printf 'a\t\bb\n'
, memorizza a
, 6 spazi e b
, e printf 'a\r\tb\n'
, per a
, 7 spazi e b
.
Ci sono altri casi in cui i terminali proveranno a copiare l'input effettivo, come quando si selezionano due righe dopo l'esecuzione in printf 'a \nb\n'
cui verrà preservato quello spazio finale invisibile. O quando si selezionano due righe non include un carattere LF quando le due righe risultano dall'avvolgimento sul margine destro.
Ora, se si desidera memorizzare l'output printf
nella X11
selezione CLIPBOARD , la cosa migliore è farlo direttamente come con:
printf 'foo\tbar\n' | xclip -sel c
Nota che quando lo incolli in xterm
o nella maggior parte degli altri terminali, in xterm
realtà lo sostituisce \n
con \r
perché questo è il carattere che xterm
invia quando premi Enter(e il driver del terminale può riportarlo in \n
).