Ich verwende ein kleines Skript in Python3, um zentrierte Vermögen in der Konsole anzuzeigen. Können Sie mir vorschlagen, wie dies in reiner Bash zu tun ist?
Datei: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)
Dann in .bashrc
Nachdem Sie es ausführbar gemacht haben chmod +x ~/center.python3
:
fortune | ~/center.python3
BEARBEITEN :Später werde ich versuchen, auf dieses OP zu antworten, basierend auf dem Kommentar, den ich hatte, aber im Moment habe ich es literarischer gemacht.
BEARBEITEN 2 :Aktualisierung des Python-Skripts zur Behebung eines Fehlers, wie von @janos zur Tab-Erweiterung aufgezeigt.
Akzeptierte Antwort:
Hier ist mein Skript 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}"
Wie es funktioniert:
- Der erste Befehl fügt jede Zeile von
stdin
ein im Arraymessage
nach der Umwandlung von Tabellen in Leerzeichen (Dank an @NominalAnimal) - Der zweite Befehl liest die Fensterbreite aus Parameter #1 und schreibt sie in die Variable
width
. Wenn kein Parameter angegeben wird, wird die tatsächliche Terminalbreite verwendet. - der dritte Befehl sendet die gesamte
message
zuawk
um den linken Rand als eine Folge von Leerzeichen zu erzeugen, die in der Variablenmargin
abgelegt wird .- Die erste awk-Zeile wird für jede Eingabezeile ausgeführt. Es berechnet
max_len
, die Länge der längsten Eingabezeile (begrenzt aufwidth
) - Die zweite awk-Zeile wird ausgeführt, wenn alle Eingabezeilen verarbeitet wurden. Es gibt eine Zeichenfolge von
(width - max_len) / 2
aus Leerzeichen
- Die erste awk-Zeile wird für jede Eingabezeile ausgeführt. Es berechnet
- der letzte Befehl gibt jede Zeile der
message
aus nach vorangestelltemmargin
zu ihnen
Test :
$ 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
Wenn Sie schließlich die Anzeige mit einer Trennlinie beenden möchten, wie in Ihrem Python-Skript, fügen Sie diese Zeile vor dem letzten printf
ein Befehl:
message+=( $(IFS=''; sed s/./─/g <<< "${message[*]}" | sort | tail -n1)$'\n' )
Es ersetzt jedes Zeichen in jeder Zeile durch ein ─
, wählen Sie mit sort | tail -n1
, und fügen Sie es am Ende der Nachricht hinzu.
Test:
$ fortune | center.sh 60
Tuesday is the Wednesday of the rest of your life.
──────────────────────────────────────────────────