Cómo usar el comando Bash printf en Linux

Publicado: 2022-06-25
Una terminal Linux sobre un fondo azul.
fatmawati achmad zaenuri/Shutterstock.com

El comando Bash printf le permite escribir en una ventana de terminal de Linux con un control más preciso y más opciones de formato que las que proporciona el comando echo . Incluso las extrañas peculiaridades de printf pueden ser útiles.

Escribir en una terminal

Es una de las partes más básicas de la interacción con un programa. El programa escribe algo en la pantalla y tú lo lees. Incluso teniendo en cuenta la convención derivada de Unix y mantenida por Linux de que los programas de línea de comandos sean lo más breves posible, muchos solo escriben en la terminal si algo sale mal. Decirle al usuario lo que está sucediendo, lo que está a punto de suceder o lo que acaba de suceder es una primitiva de programación esencial.

Cómo usar el comando Echo en Linux
RELACIONADO Cómo usar el comando Echo en Linux

El shell Bash tiene el comando echo que puede escribir texto en la ventana del terminal. Puede manejar variables y mostrar sus valores si están incluidos en la cadena, y puede usarlo en scripts o en la línea de comandos. Entonces, ¿por qué existe printf ? ¿ echo no tiene cubierto el tema de la escritura de texto? Bueno, printf ofrece una funcionalidad más allá del simple acto de escribir cadenas en las ventanas de la terminal. Le permite formatear la salida con gran flexibilidad y también tiene otros trucos.

El comando printf de Bash se basa en la función printf del lenguaje C, pero hay diferencias. Si conoce C, deberá tener cuidado con esas diferencias.

Escribir cadenas básicas

Veamos en qué se diferencian echo y printf cuando escriben cadenas en la terminal.

 eco aquí hay algunas palabras
 printf aquí hay algunas palabras 

Usando echo y printf con palabras sin comillas

El comando echo imprime todas las palabras pero printf solo imprime la primera palabra. Además, no hay una nueva línea impresa por printf . La salida se topa con el símbolo del sistema. Pero, lo primero es lo primero, para que printf actúe en todas las palabras, es necesario citarlas.

 eco aquí hay algunas palabras
 printf "aquí hay algunas palabras" 

Usando echo y printf con palabras citadas

Eso es mejor. Tenemos todas las palabras que se están imprimiendo, pero aún no obtenemos una nueva línea. Eso es porque con printf solo obtienes una nueva línea si la solicitas. Eso puede parecer una molestia, pero te permite decidir si incluir uno o no. Para hacer que printf emita una nueva línea, debe incluir " \n " en su cadena. Esta es la secuencia de escape de "nueva línea".

 eco aquí hay algunas palabras
 printf "aquí hay algunas palabras\n" 

Usando echo y printf con palabras entre comillas y el carácter de nueva línea

A veces usará una nueva línea y otras veces no. Aquí hay un caso en el que una instrucción printf usa una nueva línea y la otra no.

 printf "Cómo hacer" && printf "Geek\n" 

Usando dos printfs para crear una sola línea de texto

Debido a que el primer printf no imprime una nueva línea, la salida del segundo printf se coloca inmediatamente después de "Cómo hacer" y en la misma línea. El segundo printf usa \n para imprimir una nueva línea. Esto hace que el símbolo del sistema aparezca en la línea debajo del texto impreso.

RELACIONADO: Cómo procesar un archivo línea por línea en un script Bash de Linux

Otros personajes de escape

Aquí hay algunos caracteres de escape más que puede usar. Ya has visto “ \n ” en acción.

  • \n : Mueve hacia abajo a una nueva línea.
  • \r : Imprime un retorno de carro. Esto envía el cursor de salida de vuelta al inicio de la línea actual.
  • \t : Imprime un carácter de tabulación.
  • \v : imprime un espacio de tabulación vertical.
  • \\ : Imprime un carácter de barra invertida.
  • \” : Imprime un carácter de comillas.
  • \b : Imprime un carácter de retroceso.

El carácter de escape de retorno de carro mueve el cursor de regreso al comienzo de la línea actual .

 printf "La miel es la raíz de todos los males\rDinero\n" 

Uso del carácter de retorno de carro para volver al principio de la línea

El comando printf procesa su entrada de izquierda a derecha. La cadena se imprime como texto normal hasta que printf encuentra el carácter de escape “ \r ”. El cursor de salida se mueve de nuevo al inicio de la línea actual.

El procesamiento de la cadena se reanuda con la letra inmediatamente detrás del carácter “ \r ”. El procesamiento del resto hace que printf imprima "Dinero", sobrescribiendo la palabra "Cariño".

Las comillas “ " ” se usan para citar cadenas, y el carácter de barra invertida “ \ ” denota secuencias de escape. Si desea imprimir estos caracteres, necesita escaparlos con una barra invertida. Esto le dice a printf que los trate como caracteres literales.

 printf "Esta es una \tTab, esta es una comilla \", y esta \\ es una barra invertida\n" 

Escapar personajes para que sean tratados literalmente

Uso de variables

Usar variables con printf es muy similar a usarlas con echo . Para incluir una variable, como esta variable de entorno, antepóngala con el signo de dólar “ $ ” como de costumbre.

 printf "Directorio de inicio: $HOME\n" 

Usar printf con una variable de entorno

RELACIONADO: Cómo trabajar con variables en Bash

Cadenas de formato

Las cadenas de formato son cadenas que definen el formato de la salida. Usted proporciona texto y otros valores como argumentos para que opere la cadena de formato.

La cadena de formato puede incluir texto, secuencias de escape y especificadores de formato . Los especificadores de formato le dicen a printf qué tipo de argumento esperar, como cadenas, enteros o caracteres.

Estos son los especificadores de formato más comunes. Todos ellos están precedidos por un signo de porcentaje “ % ”. Para imprimir un signo de porcentaje, use dos signos de porcentaje juntos " %% ".

  • %s : Imprime una cadena.
  • %c : Imprime un solo carácter.
  • %d : Imprime un entero.
  • %f : imprime un número de punto flotante.
  • %u : Imprime un entero sin signo.
  • %o : Imprime un valor en octal.
  • %x : Imprime un valor en hexadecimal, en minúsculas.
  • %X : Imprime un valor en hexadecimal, en mayúsculas.
  • %e : Imprime un número de coma flotante en notación científica, en minúsculas.
  • %E : Imprime un número de punto flotante en notación científica, en mayúsculas.
  • %% : Imprime un símbolo de porcentaje "%".
 printf "Cómo hacer %s\n" "Geek"
 printf "%s%s %s\n" "Cómo" "-Para" "Geek" 

Mostrando printf aceptando "demasiados" argumentos

La cadena de formato en el primer comando incluye algo de texto propio. Pasamos la cadena "Geek" como argumento a printf . Se compara e imprime con el especificador de formato “ %s ”. Tenga en cuenta que solo hay un espacio entre la cadena de formato y la cadena de argumento. En C, necesitaría una coma para separarlos, pero con la versión Bash de printf , usar un espacio es suficiente.

La segunda cadena de formato contiene solo especificadores de formato y la secuencia de escape de nueva línea. Los tres argumentos de cadena son consumidos por cada uno de los especificadores de formato “ %s ” a su vez. Nuevamente, en C, debe colocar una coma entre cada argumento, pero el printf de Bash nos permite olvidarnos de eso.

Para imprimir diferentes tipos de argumentos, simplemente use el especificador de formato apropiado. Aquí hay una rutina de conversión de números rápida construida usando printf . Imprimiremos el valor 15 en notación decimal, octal y hexadecimal.

 printf "diciembre: %d\noct: %o\nhex: %x\n" 15 15 15 

usando printf para imprimir valores numéricos en diferentes notaciones base

Recortemos eso un poco para que el ejemplo esté menos desordenado.

 printf "Hexadecimal: %x\n" 15 

Imprimir un valor hexadecimal

La mayoría de nosotros estamos acostumbrados a ver valores hexadecimales en mayúsculas y con valores inferiores a 0x10 impresos con un cero inicial. Podemos lograrlo usando el especificador de formato hexadecimal en mayúsculas " %X " y colocando un especificador de ancho entre el signo de porcentaje " % " y el carácter " X ".

Esto le dice a printf el ancho del campo en el que se debe imprimir el argumento. El campo se rellena con espacios. Con este formato, los valores de dos dígitos se imprimirían sin relleno.

 printf "Hexadecimal: %2X\n" 15 

imprimiendo un valor hexadecimal en mayúsculas en un campo de 2 caracteres de ancho

Ahora obtenemos un valor en mayúsculas, impreso con un espacio inicial. Podemos hacer que printf complete el campo con ceros en lugar de espacios poniendo un cero delante de los dos:

 printf "Hexadecimal: %02X\n" 15 

imprimiendo un valor hexadecimal en mayúsculas en un campo de 2 caracteres de ancho rellenado con ceros

El especificador de precisión le permite establecer el número de puntos decimales para incluir en la salida.

 printf "Coma flotante: %08.3f\n" 9.243546 

Uso de modificadores de ancho y precisión con un número de punto flotante

Esto facilita la producción de tablas de resultados con una salida perfectamente alineada. Este siguiente comando también demuestra otra de las peculiaridades de Bash printf . Si hay más argumentos que especificadores de formato, los argumentos se introducen en la cadena de formato en lotes hasta que se hayan agotado todos los argumentos. El tamaño del lote que se procesa a la vez es el número de especificadores de formato en la cadena de formato. En C, se ignoran los argumentos adicionales en las llamadas a la función printf .

 printf "Flotante: %8.3f\n" 9.243546 23.665 8.0021 

Uso de modificadores de ancho y precisión para crear una tabla ordenada

También puede usar los especificadores de ancho y precisión con cadenas. Este comando imprime las cadenas en un campo de 10 caracteres de ancho.

 printf "%10s %d\n" "abrigos" 7 "zapatos" 22 "Paraguas" 3 

Usando el modificador de ancho con cadenas

De forma predeterminada, los valores se justifican a la derecha en sus campos. Para justificarlos a la izquierda, use un signo menos " - " inmediatamente detrás del signo de porcentaje " % ".

 printf "%-10s %d" "abrigos" 7 "zapatos" 22 "Paraguas" 3 

Usando un especificador de ancho justificado a la izquierda con cadenas

El especificador de precisión se puede utilizar para establecer el número máximo de caracteres que se imprimen. Estamos usando los dos puntos “ : ” para mostrar los límites del ancho del campo. No cómo se trunca la palabra "Paraguas".

 printf ":%10.6s:\n" "abrigos" "zapatos" "Paraguas"
 printf ":%-10.6s:\n" "abrigos" "zapatos" "Paraguas" 

Uso del modificador de precisión para limitar la cantidad de caracteres que se imprimen de una cadena

El especificador de ancho puede incluso pasarse como argumento . Utilice un asterisco " * " en lugar de un especificador numérico y pase el ancho como un argumento entero.

 printf "%*s\n" 20 "extremo derecho" 12 "medio" 5 "extremo izquierdo" 

Pasar el especificador de ancho como argumento a printf

Otros trucos y peculiaridades

Los especificadores de formato dentro de la cadena de formato funcionarán con valores del tipo apropiado, ya sea que se proporcionen en la línea de comando como argumentos regulares o que se generen como la salida de una expresión .

Esto imprime la suma de dos números:

 imprimir "23+32=%d\n" $((23+32)) 

Imprimir la suma de dos números

Este comando imprime el número de directorios en el directorio de trabajo actual:

 printf "Hay %d directorios\n" $(ls -d */ | wc -l) 

Contando directorios con printf

Este comando printf imprime una cadena devuelta de una llamada a otro comando.

 printf "Usuario actual: %s\n" $(whoami) 

Imprimir la salida de otro comando

Si un especificador de formato de cadena " %s " no se proporciona con un argumento, printf no imprime nada.

 printf "Uno: %s dos: %s\n" "Alfa" 

Cómo maneja printf los argumentos de cadena que faltan

Si un especificador de formato de cadena “ %s ” recibe un valor numérico por error, lo imprime como si fuera una cadena y no se queja. No intentes esto con el printf de C, sucederán cosas muy malas. Su programa probablemente fallará. Pero Bash printf lo maneja sin quejarse.

 printf "Uno: %s dos: %s\n" "Alfa" 777 

Cómo printf acepta silenciosamente enteros como valores de cadena

Si un especificador de formato entero “ %d ” no recibe ningún argumento, imprimirá cero.

 printf "Entero: %d\n" 

Cómo maneja printf los argumentos enteros que faltan

Si un especificador de formato entero “ %d ” recibe un argumento de cadena por error, Bash imprimirá un mensaje de error y printf imprimirá cero.

 printf "Entero: %d\n" "Siete" 

Cómo trata printf las cadenas que se proporcionan en lugar de los argumentos enteros

Se pueden generar símbolos incómodos usando su número Unicode o "punto de código". Estos se escapan usando la letra "u" seguida de su valor Unicode.

 printf "El símbolo del euro: \u20AC\n" 

Imprimir un valor Unicode escapado

Para incluir secuencias de escape en cadenas de argumentos , debe usar el especificador de formato “ %b ” en la cadena de formato, no el especificador de formato de cadena “ %s ”.

 printf "%s" "\u20AC\n"
 printf "%b" "\u20AC\n" 

Usando el especificador de formato %b para manejar secuencias de escape en argumentos de cadena

La primera instrucción printf no procesa el valor Unicode y no reconoce la secuencia de escape de nueva línea. La segunda instrucción printf usa el especificador de formato “ %b ”. Esto maneja correctamente el carácter Unicode y se imprime una nueva línea.

RELACIONADO: ¿Qué son las codificaciones de caracteres como ANSI y Unicode, y en qué se diferencian?

Caballos de carreras

A veces, todo lo que necesita hacer es echo un texto en la ventana del terminal. Pero cuando necesita aplicar algo de posicionamiento y formato, printf es la herramienta adecuada para el trabajo.

 printf "%b" "Es-" "Es-" "Es-" "Eso es todo amigos.\n"