El carácter ASCII del separador de unidad (ASCII 31, octal 37), es visible en Vim como a ^_
. Pero si imprimo el mismo archivo en la terminal, el personaje es invisible. Esto hace que los campos de una línea se atasquen:
# 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
Supongo que puedo hacer que el separador de unidades sea visible con cat -v:
cat -v delim.txt
first field^_second field^_last field
Pero esto es bastante engorroso. ¿Por qué el separador de unidades no tiene una representación visible cuando se imprime en stdout en el shell Bash? Ni siquiera puedo copiar y pegar la salida del shell correctamente; el separador de unidad se pierde en el proceso.
Respuestas:
El carácter separador de unidades (
US
), también conocido comoIS1
, está en lacntrl
clase de caracteres y no está en laprint
clase de caracteres. Es un carácter de control destinado a organizar el texto en grupos, para programas diseñados para hacer uso de esa información . En general, los caracteres no imprimibles probablemente serán interpretados y representados de manera diferente en diferentes programas o entornos.La razón por la que lo ves representado como
^_
en Vim es porque Vim es un editor interactivo. Puede representar libremente caracteres no imprimibles como quiera, siempre y cuando el carácter binario correcto esté escrito en el disco.No puede obtener el mismo comportamiento en el shell porque los programas de shell de Unix están escritos para operar y pasar texto sin formato entre sí. Cuando crea
cat
un archivo, el texto que se escribe en el terminal debe ser lo que realmente está en el archivo.Entonces eso deja al dispositivo terminal interpretar el personaje. Y resulta que algunos emuladores de terminal hacen que el
US
personaje sea diferente de los demás. Engnome-terminal
(o cualquiervte
terminal basado en), el personaje se representará como un cuadro que contiene el código hexadecimal001F
. Enxterm
orxvt
, el personaje es realmente invisible.fuente
US
es totalmente invisible. Cuando inserto ese carácter en un terminal conCtrl+/
(confirmado mediante<C-v><C-/>
), elimina una cantidad impredecible de texto en la línea. No entiendo completamente su comportamiento, pero parece tener principalmente algún tipo de efecto de "pestaña inversa" donde, en lugar de insertar una cantidad de espacios, elimina una cantidad de caracteres, pero a veces inserta texto al azar, por lo que es confuso .El separador de unidades está en el rango ASCII de caracteres de control y, por lo tanto, no tiene (o no debería tener) una representación visual.
Vim y algunos otros editores los muestran, para que pueda editarlos. Como te diste cuenta
cat -v
también lo muestra. La página de manual muestra, esa-v
es la forma abreviada de--show-nonprinting
, lo que hace que reemplace los caracteres que no se imprimen con una representación imprimible, que no es el contenido original del archivo y, por lo tanto, podría causar problemas, si la salida es realmente a otro programa .La representación que ve ya insinúa que es un carácter de control: un carácter antepuesto con a
^
es una notación común para Ctrl+ el carácter, que es la combinación de teclas que produce este carácter en un terminal. Ctrl+ _le permitirá ingresar el separador de unidades en vim, por ejemplo. Pero otro editor o algún visor de GUI podría mostrar el código hexadecimal, un marcador de posición o algo completamente diferente.Como su terminal no imprime los caracteres de control, tampoco se copia al seleccionar el texto (los caracteres de espacio en blanco como nueva línea y tabulación son una excepción aquí, que también son caracteres de control). Otro ejemplo de caracteres de control en el terminal que generalmente se ignoran al copiar son los códigos de color, que son un
ESC
carácter seguido del código para colorear el texto.Entonces, para mostrar los caracteres en su terminal, no hay otra manera que usar un programa que reemplace el separador de la unidad con algún carácter imprimible.
fuente
Un poco al margen de las otras (muy buenas) respuestas, si desea alterar solo el carácter de control
^_
al mostrar el contenido del archivo, es posible que desee transliterarlo utilizando latr
utilidad (y un poco de sintaxis compatible con bash) :Si necesita reemplazar ese carácter de control por su forma "expandida", necesitará en su
sed
lugar:Tenga en cuenta la sintaxis
$'\cX'
: esta sintaxis informa a su (shell compatible con bash) que reemplace el carácter de control correspondiente. Consulte wikipedia para obtener una lista de alias de caracteres de control utilizando la "notación de intercalación". Si no le gusta esa sintaxis, puede preferir usar la notación octal$'\037'
o hexadecimal en su$'\x1f'
lugar.fuente