GNU/Linux >> Linux Esercitazione >  >> Linux

Script di Bash per centrare Fortune/testo da Stdin/pipe?

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'array message 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 a awk per produrre il margine sinistro come una stringa di spazi che viene inserita nella variabile margin .
    • la prima riga awk viene eseguita per ogni riga di input. Calcola max_len , la lunghezza della riga di input più lunga (limitata a width )
    • 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
  • l'ultimo comando stampa ogni riga di message dopo aver anteposto margin 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.

Correlati:Script Bash per ordinare i file in cartelle alfabetiche su ReadyNAS Duo v1?

Prova:

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

Linux
  1. Passare gli argomenti della riga di comando allo script Bash?

  2. Script Bash per rimuovere il file più vecchio da una cartella?

  3. Come impostare i parametri quando Pipe Bash Script su Bash?

  4. Includere condizionatamente uno stage di pipe in uno script Bash?

  5. Esegue lo script bash dall'URL

esecuzione di script php (funzione php) in linux bash

Ottieni una riga specifica dal file di testo usando solo lo script della shell

Come reindirizzare il testo dalla riga di comando agli appunti

echo testo con nuova riga in bash

Uccidi il programma dopo aver emesso una determinata riga, da uno script di shell

come tracciare stdin dal terminale?