GNU/Linux >> Tutoriels Linux >  >> Linux

Script Bash vers Center Fortune/texte depuis Stdin/pipe ?

J'utilise un petit script en python3 pour afficher des fortunes centrées dans la console, pouvez-vous me suggérer comment faire cela en pur bash ?

fichier :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)

Puis dans .bashrc

Après l'avoir rendu exécutable chmod +x ~/center.python3 :

fortune | ~/center.python3

MODIFIER :Plus tard, j'essaierai de répondre à cet OP en fonction du commentaire que j'ai eu, mais pour l'instant je l'ai rendu plus alphabétisé.

MODIFICATION 2 :mise à jour du script python pour résoudre un bogue comme l'a souligné @janos à propos de l'expansion des onglets.

Réponse acceptée :

Voici mon 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}"

Comment ça marche :

  • la première commande place chaque ligne de stdin dans le tableau message après avoir converti les tabulations en espaces (merci à @NominalAnimal)
  • la deuxième commande lit la largeur de la fenêtre à partir du paramètre 1 et la place dans la variable width . Si aucun paramètre n'est donné, la largeur réelle du terminal est utilisée.
  • la troisième commande envoie tout le message à awk afin de produire la marge de gauche sous la forme d'une chaîne d'espaces qui est placée dans la variable margin .
    • la première ligne awk est exécutée pour chaque ligne d'entrée. Il calcule max_len , la longueur de la ligne d'entrée la plus longue (plafonnée à width )
    • la deuxième ligne awk est exécutée lorsque toutes les lignes d'entrée ont été traitées. Il imprime une chaîne de (width - max_len) / 2 espaces blancs
  • la dernière commande imprime chaque ligne de message après avoir ajouté margin à eux

Tester :

$ 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

Enfin, si vous souhaitez terminer l'affichage par une ligne de séparation, comme dans votre script Python, ajoutez cette ligne avant le dernier printf commande :

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

Ce qu'il fait, c'est remplacer chaque caractère de chaque ligne par un , sélectionnez le plus long avec sort | tail -n1 , et ajoutez-le à la fin du message.

En relation :Script Bash pour trier les fichiers dans des dossiers alphabétiques sur ReadyNAS Duo v1 ?

Test :

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

Linux
  1. Passer les arguments de la ligne de commande au script Bash ?

  2. Script Bash :vérifier si un fichier est un fichier texte ?

  3. Modifier un courrier entrant de Text/plain à Text/html ?

  4. Comment définir les paramètres lorsque Pipe Bash Script to Bash ?

  5. Inclure conditionnellement une étape Pipe dans un script Bash ?

exécution d'un script php (fonction php) sous linux bash

Obtenir une ligne spécifique à partir d'un fichier texte en utilisant uniquement un script shell

script bash ajoute du texte à la première ligne d'un fichier

Comment diriger le texte de la ligne de commande vers le presse-papiers

Tuer le programme après avoir sorti une ligne donnée, à partir d'un script shell

comment tracer stdin depuis le terminal?