¿Cómo hago eco de uno o más caracteres de tabulación usando un script de bash? Cuando corro este codigo
res=' 'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]
Entiendo esto
res=[ x] # that is [<space>x]
echo -e ' \t '
hará eco de 'espacio de la nueva línea de espacio de la pestaña' (-e
significa 'habilitar la interpretación de escapes de barra invertida'):
$ echo -e ' \t ' | hexdump -C
00000000 20 09 20 0a | . .|
Use printf
, no echo
.
Hay varias versiones diferentes del comando echo
. Hay /bin/echo
(que puede ser o no _ GNU Coreutils versión, dependiendo del sistema), y el comando echo
está integrado en la mayoría de los shells. Las diferentes versiones tienen diferentes (o ninguna) manera de especificar o deshabilitar escapes para los caracteres de control.
printf
, por otro lado, tiene mucha menos variación. Puede existir como un comando, generalmente /bin/printf
, y está integrado en algunos shells (bash y zsh lo tienen, tcsh y ksh no), pero las diferentes versiones son mucho más similares entre sí que las diferentes versiones de echo
. Y no tiene que recordar las opciones de la línea de comandos (con algunas excepciones; GNU Coreutils printf acepta --version
y --help
, y el bash printf incorporado acepta -v var
para almacenar la salida en una variable).
Para su ejemplo:
res=' 'x # res = "\t\tx"
printf '%s\n' "[$res]"
Y ahora es el momento para que admita que echo
funcionará igual de bien para el ejemplo que está preguntando; solo necesitas poner comillas dobles alrededor del argumento:
echo "[$res]"
como escribió kmkaplan (hace dos años y medio, me di cuenta!). El problema con tus comandos originales:
res=' 'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]
no es con echo
; es que la Shell reemplazó la pestaña con un espacio antes de que echo
la viera.
echo
está bien para resultados simples, como echo hello world
, pero debe usar printf
cuando quiera hacer algo más complejo. Usted puede conseguir que echo
funcione, pero es probable que el código resultante falle cuando lo ejecute con una implementación echo
diferente o un Shell diferente.
Ponga su cadena entre doble comillas:
echo "[$res]"
También puedes probar:
echo Hello$'\t'world.
necesitas usar una bandera para el eco, entonces puedes
echo -e "\t\t x"
El uso de eco para imprimir valores de variables es un error común de Bash. Link de referencia:
Desde la página de manual de bash:
Las palabras de la forma $ 'cadena' se tratan especialmente. La palabra se expande a la cadena, con caracteres de escape de barra invertida reemplazados según lo especificado por el estándar ANSI C.
Así que puedes hacer esto:
echo $'hello\tworld'
Use la combinación de teclas verbatim, ^V
(CTRL+V
, C-v
, lo que sea).
Cuando escribe ^V
en el terminal (o en la mayoría de los editores de Unix), se toma el siguiente carácter textualmente. Puede usar esto para escribir un carácter de tabulación literal dentro de una cadena de la que está haciendo eco.
Algo así como las siguientes obras:
echo "^V<tab>" # CTRL+V, TAB
Bash docs (q.v., "quoted-insert")
quoted-insert (C-q, C-v) Agregue el siguiente carácter que escriba a la línea literalmente. Así es como insertar secuencias de teclas como C-q, por ejemplo.
nota al margen: de acuerdo con estoALT+TAB
debería hacer lo mismo, pero todos hemos vinculado esa secuencia al cambio de ventana, por lo que no podemos usarla
insertar pestaña (M-TAB) Insertar un carácter de pestaña.
-
Nota: puedes usar esta estrategia con todo tipo de personajes inusuales. Como un retorno de carro:
echo "^V^M" # CTRL+V, CTRL+M
Esto se debe a que el retorno de carro es ASCII 13, yMes la décimotercera letra del alfabeto, por lo que cuando escribe ^M
, obtiene la 13 ª [ASCII personaje. Puede verlo en acción usando ls^M
, en un Aviso vacío, que insertará un retorno de carro, lo que hará que el Indicador actúe como si presionara retorno. Cuando estos caracteres se interpretan normalmente, literalmente obtiene el carácter literal.
Si desea utilizar echo "a\tb"
en un script, ejecute el script como:
# sh -e myscript.sh
Alternativamente, puede otorgar a myscript.sh el permiso de ejecución y luego ejecutar el script.
# chmod +x myscript.sh
# ./myscript.sh
res="\t\tx"
echo -e "[${res}]"