GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Bash-Skript zum Zentrieren von Fortune/Text von Stdin/Pipe?

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 Array message 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 zu awk um den linken Rand als eine Folge von Leerzeichen zu erzeugen, die in der Variablen margin 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 auf width )
    • Die zweite awk-Zeile wird ausgeführt, wenn alle Eingabezeilen verarbeitet wurden. Es gibt eine Zeichenfolge von (width - max_len) / 2 aus Leerzeichen
  • der letzte Befehl gibt jede Zeile der message aus nach vorangestelltem margin 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.

Siehe auch:Bash-Skript zum Sortieren von Dateien in alphabetische Ordner auf ReadyNAS Duo v1?

Test:

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

Linux
  1. Verhindern, dass ein Bash-Skript gleichzeitig ausgeführt wird

  2. Befehlszeilenargumente an Bash-Skript übergeben?

  3. Bash-Skript:Prüfen, ob eine Datei eine Textdatei ist?

  4. Eine eingehende Mail von Text/plain zu Text/html ändern?

  5. Wie werden Parameter eingestellt, wenn Bash-Skript an Bash übergeben wird?

Bash-Skript zum Entfernen der ältesten Datei aus einem Ordner?

In Bash-Skript zur/von der Zwischenablage leiten

Bash-Skript fügt Text an die erste Zeile einer Datei an

matlab Skript von der Linux-Befehlszeile ausführen

Beenden Sie das Programm, nachdem es eine bestimmte Zeile aus einem Shell-Skript ausgegeben hat

Wie kann man stdin vom Terminal aus plotten?