Sto usando un piccolo script in python3 per mostrare fortune centrate su console, puoi suggerirmi come farlo in pure bash?
file:center.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)
Quindi in .bashrc
Dopo averlo reso eseguibile chmod +x ~/center.python3
:
fortune | ~/center.python3
MODIFICA :Più tardi cercherò di rispondere a questo OP in base al commento che avevo, ma per ora l'ho reso più alfabetizzato.
MODIFICA 2 :aggiornamento dello script python per risolvere un bug come sottolineato da @janos sull'espansione delle schede.
Risposta accettata:
Ecco il mio 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}"
Come funziona:
- il primo comando inserisce ogni riga di
stdin
nell'arraymessage
dopo aver convertito le tabulazioni in spazi (grazie a @NominalAnimal) - il secondo comando legge la larghezza della finestra dal parametro #1 e la inserisce nella variabile
width
. Se non viene fornito alcun parametro, viene utilizzata la larghezza effettiva del terminale. - il terzo comando invia l'intero
message
aawk
per produrre il margine sinistro come una stringa di spazi che viene inserita nella variabilemargin
.- la prima riga awk viene eseguita per ogni riga di input. Calcola
max_len
, la lunghezza della riga di input più lunga (limitata awidth
) - la seconda riga awk viene eseguita quando tutte le righe di input sono state elaborate. Stampa una stringa di
(width - max_len) / 2
caratteri di spazio bianco
- la prima riga awk viene eseguita per ogni riga di input. Calcola
- l'ultimo comando stampa ogni riga di
message
dopo aver antepostomargin
a loro
Prova :
$ 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
Infine, se vuoi terminare la visualizzazione con una linea di separazione, come nel tuo script Python, aggiungi questa riga prima dell'ultimo printf
comando:
message+=( $(IFS=''; sed s/./─/g <<< "${message[*]}" | sort | tail -n1)$'\n' )
Quello che fa è sostituire ogni carattere in ogni riga con un ─
, seleziona il più lungo con sort | tail -n1
e aggiungilo alla fine del messaggio.
Prova:
$ fortune | center.sh 60
Tuesday is the Wednesday of the rest of your life.
──────────────────────────────────────────────────