GNU/Linux >> Tutoriales Linux >  >> Linux

Bash Script para Center Fortune/texto de Stdin/pipe?

Estoy usando un pequeño script en python3 para mostrar fortunas centradas en la consola, ¿puede sugerirme cómo hacer esto en bash puro?

archivo:centro.python3

#!/usr/bin/env python3

import sys, os

linelist = list(sys.stdin)

# gets the biggest line
biggest_line_size = 0
for line in linelist:
    line_lenght = len(line.expandtabs())
    if line_lenght > biggest_line_size:
        biggest_line_size = line_lenght

columns = int(os.popen('tput cols', 'r').read())
offset = biggest_line_size / 2
perfect_center = columns / 2
padsize =  int(perfect_center - offset)
spacing = ' ' * padsize # space char

text = str()
for line in linelist:
    text += (spacing + line)

divider = spacing + ('─' * int(biggest_line_size)) # unicode 0x2500
text += divider

print(text, end="\n"*2)

Luego en .bashrc

Después de hacerlo ejecutable chmod +x ~/center.python3 :

fortune | ~/center.python3

EDITAR :Más tarde intentaré responder a este OP basado en el comentario que tenía, pero por ahora lo hice más alfabetizado.

EDITAR 2 :actualizando el script de python para resolver un error como lo señaló @janos sobre la expansión de pestañas.

Respuesta aceptada:

Aquí está mi script center.sh :

#!/bin/bash

readarray message < <(expand)

width="${1:-$(tput cols)}"

margin=$(awk -v "width=$width" '
    { max_len = length > width ? width : length > max_len ? length : max_len }
    END { printf "%" int((width - max_len + 1) / 2) "s", "" }
' <<< "${message[@]}")

printf "%s" "${message[@]/#/$margin}"

Cómo funciona:

  • el primer comando pone cada línea de stdin en la matriz message después de convertir tabulaciones a espacios (gracias a @NominalAnimal)
  • el segundo comando lee el ancho de la ventana del parámetro #1 y lo coloca en la variable width . Si no se proporciona ningún parámetro, se utiliza el ancho de terminal real.
  • el tercer comando envía el message completo a awk para producir el margen izquierdo como una cadena de espacios que se coloca en la variable margin .
    • la primera línea awk se ejecuta para cada línea de entrada. Calcula max_len , la longitud de la línea de entrada más larga (limitada a width )
    • la segunda línea awk se ejecuta cuando se han procesado todas las líneas de entrada. Imprime una cadena de (width - max_len) / 2 caracteres de espacio en blanco
  • el último comando imprime cada línea de message después de anteponer margin a ellos

Prueba:

$ fortune | cowthink | center.sh
                    _______________________________________
                   ( English literature's performing flea. )
                   (                                       )
                   ( -- Sean O'Casey on P. G. Wodehouse    )
                    ---------------------------------------
                           o   ^__^
                            o  (oo)\_______
                               (__)\       )\/\
                                   ||----w |
                                   ||     ||

$ echo $'|\tTAB\t|' | center.sh 20
  |       TAB     |

$ echo "A line exceeding the maximum width" | center.sh 10
A line exceeding the maximum width

Finalmente, si desea finalizar la visualización con una línea de separación, como en su secuencia de comandos de Python, agregue esta línea antes del último printf comando:

message+=( $(IFS=''; sed s/./─/g <<< "${message[*]}" | sort | tail -n1)$'\n' )

Lo que hace es reemplazar cada carácter en cada línea con un , seleccione el más largo con sort | tail -n1 y agréguelo al final del mensaje.

Relacionado:¿Script Bash para ordenar archivos en carpetas alfabéticas en ReadyNAS Duo v1?

Prueba:

$ fortune | center.sh  60
     Tuesday is the Wednesday of the rest of your life.
     ──────────────────────────────────────────────────

Linux
  1. Evitar que un script bash se ejecute simultáneamente

  2. Bash Script:¿Comprobar si un archivo es un archivo de texto?

  3. ¿Modificar un correo entrante de texto/sin formato a texto/html?

  4. ¿Cómo establecer parámetros cuando Pipe Bash Script to Bash?

  5. ¿Incluir condicionalmente una etapa de tubería en un script Bash?

ejecutar script php (función php) en linux bash

Obtenga una línea específica del archivo de texto usando solo un script de shell

script bash agrega texto a la primera línea de un archivo

Cómo canalizar texto desde la línea de comando al portapapeles

Eliminar una determinada línea del archivo de historial de Bash

cómo trazar stdin desde la terminal?