Estoy tratando de imprimir dos cadenas separadas por una TAB. Yo he tratado:
echo -e 'foo\tbar'
printf '%s\t%s\n' foo bar
Ambos imprimen:
foo bar
Donde el espacio en blanco entre los dos es en realidad 5 espacios (según la selección de la salida con el mouse en Putty).
También intenté usar CTRL + V y presionar TAB al escribir el comando, con el mismo resultado.
¿Cuál es la forma correcta de forzar que la pestaña se imprima como pestaña, para que pueda seleccionar la salida y copiarla en otro lugar, con pestañas?
Y la pregunta secundaria: ¿por qué bash está expandiendo las pestañas en espacios?
Actualización : Aparentemente, este es un problema de Putty: /superuser/656838/how-to-make-putty-display-tabs-within-a-file-instead-of-changing-them-to -espacios
bash
putty
whitespace
tabs
Asu
fuente
fuente
printf '%s\\t%s\n' foo bar
foo\tbar
...$'\t'
como un tabulador. Por lo tanto, siempre puede concatenar cadenas como esta, por ejemplo, como asignación:v='This is'$'\t''a test'
y la imprime literalmente, por ejemploprintf '%s' "$v"
Respuestas:
Como dijo ilkkachu, este no es un problema con bash, sino con el emulador de terminal que convierte las pestañas en espacios en la salida.
Verificando diferentes terminales, putty, xterm y konsole convierten las pestañas en espacios, mientras que urxvt y gnome-terminal no lo hacen. Entonces, otra solución es cambiar terminales.
fuente
stty tab3
.No, no es. No en la salida de
echo
oprintf
.Este es un problema diferente. No se trata del shell sino del emulador de terminal, que convierte las pestañas en espacios en la salida. Muchos, pero no todos lo hacen.
Puede ser más fácil redirigir la salida con pestañas a un archivo y copiarla desde allí, o usarla
unexpand
en la salida para convertir espacios en pestañas. (Aunque tampoco puede saber con qué espacios en blanco eran las pestañas, y lo convertirá todo en pestañas, si es posible). Esto, por supuesto, dependerá de qué, exactamente, necesita hacer con la salida.fuente
En
printf '%s\t%s\n' foo bar
,printf
hace salidafoo<TAB>bar<LF>
.f
,o
,b
,a
Yr
son caracteres gráficos de un solo ancho.Al recibir esos caracteres, el terminal mostrará el glifo correspondiente y moverá el cursor una columna hacia la derecha, a menos que ya haya alcanzado el borde derecho de la pantalla (papel en máquinas de escribir originales), en cuyo caso puede alimentar una línea y regrese al borde izquierdo de la pantalla (ajuste) o simplemente descarte el carácter según el terminal y cómo se haya configurado.
<Tab>
y<LF>
son dos personajes de control .<LF>
(también conocido como nueva línea) es el delimitador de línea en texto Unix, pero para terminales, solo alimenta una línea (mueve el cursor una posición hacia abajo). Por lo tanto, el controlador de terminal en el kernel realmente lo traducirá a<CR>
(volver al borde izquierdo de la pantalla),<LF>
(cursor hacia abajo) (stty onlcr
generalmente activado por defecto).<Tab>
le dice al terminal que mueva el cursor a la siguiente parada de tabulación (que en la mayoría de los terminales están separados por 8 posiciones por defecto, pero también se puede configurar para que se configure en cualquier lugar) sin llenar el espacio con espacios en blanco.Entonces, si esos caracteres se envían a una terminal con tabulaciones cada 8 columnas mientras el cursor está al comienzo de una línea vacía, eso dará como resultado:
impreso en la pantalla en esa línea. Si se envían mientras el cursor está en la tercera posición en una línea que contiene
xxxxyyyyzzzz
, eso dará como resultado:En terminales que no admiten tabulación, el controlador de terminal se puede configurar para traducir esas pestañas a secuencias de espacios. (
stty tab3
)El carácter SPC, en las máquinas de escribir telescópicas originales, movería el cursor hacia la derecha, mientras que la tecla de retroceso (
\b
) lo movería hacia la izquierda. Ahora en las terminales modernas, SPC se mueve hacia la derecha y también borra (escribe un carácter de espacio como es de esperar). Entonces el colgante de\b
tenía que ser algo más nuevo que ASCII. En la mayoría de los terminales modernos, en realidad es una secuencia de caracteres:<Esc>
,[
,C
.Hay más secuencias de escape para mover
n
personajes a la izquierda, derecha, arriba, abajo o en cualquier posición de la pantalla. Hay otras secuencias de escape para borrar (llenar con espacios en blanco) partes de líneas o regiones de la pantalla, etc.Esas secuencias se utilizan normalmente por aplicaciones visuales como
vi
,lynx
,mutt
,dialog
donde el texto está escrito en posiciones arbitrarias en la pantalla.Ahora, todos los emuladores de terminal X11 y algunos otros no X11 como GNU le
screen
permiten seleccionar áreas de la pantalla para copiar y pegar. Cuando selecciona una parte de lo que ve en elvi
editor, no desea copiar todas las secuencias de escape que se han utilizado para producir esa salida. Desea seleccionar el texto que ve allí.Por ejemplo, si ejecutas:
Que simula una sesión de editor en la que ingresa
abC
, vuelve al principio, reemplazaab
conAC
,C
conB
, mueve a la siguiente tabulación, luego una columna más a la derecha, luego dos columnas a la izquierda, luego ingresaD
.Lo ves:
Es decir,
ABC
un espacio de 4 columnas yD
.Si selecciona eso con el mouse en
xterm
oputty
, se almacenarán en la selecciónABC
, 4 caracteres de espacio yD
, noabC<CR>AC<BS>B<Tab><Esc>[C<BS><BS>D
.Lo que termina en la selección es lo que ha sido enviado
printf
pero procesado posteriormente tanto por el controlador de terminal como por el emulador de terminal.Para otros tipos de transformación, vea el
<U+0065><U+0301>
(e
seguido de un acento agudo combinado) cambiado a<U+00E9>
(é
la forma precompuesta) porxterm
.O
echo abc
eso termina siendo traducidoABC
por el controlador de terminal antes de enviarlo a la terminal después de astty olcuc
.Ahora,
<Tab>
like<LF>
es uno de esos pocos caracteres de control que a veces se encuentran en los archivos de texto (también<CR>
en los archivos de texto MSDOS y, a veces,<FF>
en el salto de página).Por lo tanto, algunos emuladores de terminal eligen copiarlos cuando sea posible en los búferes de copiar y pegar para preservarlos (generalmente ese no es el caso
<CR>
ni tampoco<LF>
).Por ejemplo, en terminales basados en VTE como
gnome-terminal
, puede ver que, cuando selecciona la salida deprintf 'a\tb\n'
en una línea vacía, engnome-terminal
realidad se almacenaa\tb
en la selección X11 en lugar dea
7 espacios yb
.Sin embargo, para la producción de
printf 'a\t\bb\n'
, almacenaa
, 6 y espaciosb
, y paraprintf 'a\r\tb\n'
,a
, 7 y espaciosb
.Hay otros casos en los que los terminales intentarán copiar la entrada real, como cuando selecciona dos líneas después de ejecutar
printf 'a \nb\n'
donde se preservará ese espacio final invisible. O cuando se seleccionan dos líneas no incluye un carácter LF cuando las dos líneas resultan del ajuste en el margen derecho.Ahora, si desea almacenar la salida de
printf
en el CLIPBOARDX11
select, lo mejor es hacerlo directamente como:Tenga en cuenta que cuando pega eso en la
xterm
mayoría de los otros terminales, enxterm
realidad lo reemplaza\n
con\r
porque ese es el carácter quexterm
envía cuando presiona Enter(y el controlador del terminal puede volver a traducirlo\n
).fuente
X11
es lo que maneja la selección de copiar y pegar en emuladores de terminal comoxterm
oputty
en Unix. Otros emuladores de terminal pueden tener su propio mecanismo de copiar y pegar y formas de almacenar contenido arbitrario allí, como los comandosreadbuf
yregister
en la pantalla GNU.