Comando printf de Shell

En el capítulo anterior aprendimos el comando echo de Shell; en este capítulo aprenderemos otro comando de salida de Shell, printf.

printfprintf (print formatted) es un comando de Shell para salida formateada, que proviene de laprintf()función de C.

yechoA diferencia de echo,printfno añade automáticamente saltos de línea y puede controlar con precisión el formato de salida.

printf está definido por el estándar POSIX, por lo que los scripts que usan printf tienen mejor portabilidad que los que usan echo.

printf usa argumentos separados por texto citado o espacios; podemosprintfusar cadenas de formato en format-string, y también especificar el ancho, la alineación a la izquierda o derecha, etc. El printf predeterminado, a diferencia deechoecho, no añade automáticamente saltos de línea; podemos añadirlos manualmente.\n。

¿Por qué usar printf?

  1. Control de formato: puede especificar el ancho de campo, la precisión y la alineación
  2. Seguridad de tipos: diferentes tipos de datos (enteros, flotantes, cadenas, etc.) tienen especificadores de formato correspondientes
  3. Portabilidad: el comportamiento es más consistente en diferentes sistemas y shells
  4. Salida compleja: adecuado para generar tablas, informes y otras salidas estructuradas

Sintaxis básica

La sintaxis del comando printf:

printf  format-string  [arguments...]

Descripción de parámetros:

  • format-string: una cadena que contiene caracteres normales y especificadores de formato
  • arguments...: variables o valores correspondientes a los especificadores de formato

Los especificadores de formato comienzan con%un carácter, seguido de uno o más caracteres, para especificar el formato de salida. Los especificadores de formato comunes incluyen:

  • %s: cadena
  • %d: entero decimal
  • %f: número flotante
  • %c: carácter
  • %x: número hexadecimal
  • %o: número octal
  • %b: número binario
  • %e: número flotante en notación científica

Flujo de trabajo

  1. Analizar la cadena de formato; los caracteres normales se emiten directamente
  2. Cuando se encuentra un especificador de formato (que comienza con%"%):
    • Leer el siguiente argumento
    • Procesar el argumento según el formato especificado por el especificador
    • Insertar el resultado en la salida
  3. Después de procesar todos los especificadores de formato, se emite el resultado final

Ejemplos prácticos

1. Uso básico

Ejemplo

# Salida de cadena simple
printf "Hello, World!\n"

# Salida con variables
name="Alice"
printf "Hello, %s\n" "$name"

Ejecución y salida:

Ejemplo

$ bash script.sh
Hello, World!
Hello, Alice

2. Especificadores de formato comunes

Ejemplo

# Entero
printf "Decimal: %d\nHex: %x\nOctal: %o\n" 255 255 255

# Flotante
printf "Float: %f\nScientific: %e\n" 3.14159 3.14159

# Cadena
printf "Name: %s\n" "Bob"

# Carácter
printf "First letter: %c\n" "A"

Resultado de la ejecución:

Decimal: 255
Hex: ff
Octal: 377
Float: 3.141590
Scientific: 3.141590e+00
Name: Bob
First letter: A

3. Control de formato

Ejemplo

# Ancho de campo y alineación
printf "|%10s|\n|%-10s|\n" "right" "left"

# Ceros iniciales en números
printf "Year: %04d\n" 23

# Precisión de números flotantes
printf "Pi: %.2f\n" 3.14159

Resultado de la ejecución:

|     right|
|left      |
Year: 0023
Pi: 3.14

4. Manejo de múltiples argumentos

Ejemplo

printf "%-10s %5d %8.2f\n" "Apple" 5 2.5 "Orange" 3 1.75

Resultado de la ejecución:

Apple          5     2.50
Orange         3     1.75

Aplicaciones extendidas

1. Crear salida de tablas

Ejemplo

#!/bin/bash

# Encabezado
printf "%-15s %10s %10s %10s\n" "Item" "Quantity" "Price" "Total"

# Línea separadora
printf "%-15s %10s %10s %10s\n" "---------------" "----------" "----------" "----------"

# Filas de datos
printf "%-15s %10d %10.2f %10.2f\n" "Notebook" 3 2.50 7.50
printf "%-15s %10d %10.2f %10.2f\n" "Pen" 5 1.20 6.00
printf "%-15s %10d %10.2f %10.2f\n" "Eraser" 2 0.50 1.00

# Fila de total
printf "%-15s %10s %10s %10.2f\n" "" "" "Total:" 14.50

Salida resultante:

Item            Quantity      Price      Total
--------------- ---------- ---------- ----------
Notebook               3       2.50       7.50
Pen                    5       1.20       6.00
Eraser                 2       0.50       1.00
                       Total:             14.50

2. Implementación de barra de progreso

Ejemplo

#!/bin/bash

for i in {1..20}; do
    printf "\rProgress: [%-20s] %d%%" $(printf "%${i}s" | tr ' ' '#') $((i*5))
    sleep 0.1
done
printf "\n"

Efecto de ejecución: muestra una barra de progreso que crece gradualmente

3. Salida de colores

Ejemplo

#!/bin/bash

RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

printf "${RED}Error:${NC} Something went wrong\n"
printf "${GREEN}Success:${NC} Operation completed\n"

4. Salida con formato

A continuación, usaré un script para demostrar el potente funcionamiento de printf:

Ejemplo

#!/bin/bash
# autor: Tutorial de novatos
# url:www.example.com
 
printf "%-10s %-8s %-4s\n"Nombre Sexo Peso(kg)
printf "%-10s %-8s %-4.2f\n"Guo Jing Masculino66.1234
printf "%-10s %-8s %-4.2f\n"Yang Guo Masculino48.6543
printf "%-10s %-8s %-4.2f\n"Guo Fu Femenino47.9876

Ejecute el script; el resultado es el siguiente:

姓名     性别   体重kg
郭靖     男      66.12
杨过     男      48.65
郭芙     女      47.99

%s %c %d %fSon todos especificadores de formato,%s%s genera una cadena,%d%d genera un entero,%c%c genera un carácter,%f%f genera un número real, en forma decimal.

%-10s-10s se refiere a un ancho de 10 caracteres (-el '-' indica alineación a la izquierda; sin él, alineación a la derecha). Cualquier carácter se mostrará dentro de un ancho de 10 caracteres; si es insuficiente, se rellena automáticamente con espacios; si lo supera, el contenido también se mostrará por completo.

%-4.2f%.2f se refiere a formatear como decimal, donde.2.2 indica conservar 2 decimales.

Ejemplo

#!/bin/bash
# autor: Tutorial de novatos
# url:www.example.com
 
# format-string está entre comillas dobles
printf "%d %s\n" 1 "abc"

# Las comillas simples y dobles tienen el mismo efecto
printf '%d %s\n' 1 "abc"

# También se puede emitir sin comillas
printf %s abcdef

# El formato solo especifica un argumento, pero los argumentos adicionales se emitirán según dicho formato; format-string se reutiliza
printf %s abc def

printf "%s\n" abc def

printf "%s %s %s\n" a b c d e f g h i j

# Si no hay arguments, %s se reemplaza por NULL, %d se reemplaza por 0
printf "%s and %d \n"

Ejecute el script; el resultado es el siguiente:

1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j  
 and 0

Secuencias de escape de printf

SecuenciaDescripción
\aCarácter de alerta, normalmente el carácter BEL del código ASCII
\bRetroceso
\cSuprime (no muestra) cualquier carácter de nueva línea final en el resultado de salida (solo es válido en cadenas de argumentos bajo el control del indicador de formato %b); además, cualquier carácter restante en los argumentos, cualquier argumento siguiente y cualquier carácter restante en la cadena de formato se ignoran.
\fAvance de página (formfeed)
\n Nueva línea
\rRetorno de carro (Carriage return)
\tTabulación horizontal
\vTabulación vertical
\\Un carácter de barra invertida literal
\ddd Carácter que representa un valor octal de 1 a 3 dígitos. Solo es válido en la cadena de formato.
\0dddCarácter que representa un valor octal de 1 a 3 dígitos.

Ejemplo

$ printf "a string, no processing:<%s>\n" "A\nB"
a string, no processing:<A\nB>

$ printf "a string, no processing:<%b>\n" "A\nB"
a string, no processing:<A
B>

$ printf "www.example.com \a"
www.example.com $                  # Sin salto de línea

Resumen de puntos clave

Repaso de conocimientos clave

Concepto Descripción Ejemplo
Sintaxis básica printf "format" args printf "%s" "hello"
Especificadores de formato Comienzan con %, especifican el tipo de dato y el formato %d(entero),%f(flotante)
Caracteres de escape Representación de caracteres especiales \n(nueva línea),\t(tabulación)
Ancho de campo Controla el ancho mínimo de salida %10s(10 caracteres de ancho)
Control de precisión Número de decimales en flotantes %.2f(2 decimales)

Tabla de referencia rápida de especificadores de formato comunes

Especificador Uso Ejemplo de entrada Ejemplo de salida
%s Cadena "text" text
%d Entero decimal 255 255
%x Entero hexadecimal 255 ff
%f Número flotante 3.14159 3.141590
%.2f 2 decimales 3.14159 3.14
%c Carácter único "A" A
%% Signo de porcentaje - %
Otras extensiones