In printf '%s\t%s\n' foo bar, printfgenera output foo<TAB>bar<LF>.
f, o, b, aE rsono 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 onlcrgeneralmente 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 \bdoveva 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 npersonaggi 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, dialogin cui il testo è scritto in posizioni arbitrarie sullo schermo.
Ora, tutti gli emulatori di terminale X11 e alcuni altri non X11 come GNU screenti consentono di selezionare le aree dello schermo per il copia incolla. Quando selezioni una parte di ciò che vedi vinell'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 abcon AC, Ccon 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 xtermo putty, memorizzeranno nella selezione ABC4 caratteri spaziali e Dnon abC<CR>AC<BS>B<Tab><Esc>[C<BS><BS>D.
Ciò che finisce nella selezione è ciò che è stato inviato printfma post-elaborato sia dal driver del terminale che dall'emulatore di terminale.
Per altri tipi di trasformazione, vedere <U+0065><U+0301>( eseguito da un accento acuto combinato) modificato in <U+00E9>( éla forma precomposta) da xterm.
O echo abcche finisce per essere tradotto ABCdal 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-terminalrealtà memorizza a\tbnella selezione X11 anziché a7 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 printfnella X11selezione CLIPBOARD , la cosa migliore è farlo direttamente come con:
printf 'foo\tbar\n' | xclip -sel c
Nota che quando lo incolli in xtermo nella maggior parte degli altri terminali, in xtermrealtà lo sostituisce \ncon \rperché questo è il carattere che xterminvia quando premi Enter(e il driver del terminale può riportarlo in \n).