web-dev-qa-db-fra.com

Alignement de la sortie du script Bash Shell

Mon script:

date
echo -e "${YELLOW}Network check${NC}\n\n"

while read hostname
do

ping -c 1 "$hostname" > /dev/null 2>&1 &&

echo -e "Network $hostname : ${GREEN}Online${NC}" ||
echo -e "${GRAY}Network $hostname${NC} : ${RED}Offline${NC}"

done < list.txt
        sleep 30
clear
done

Génère des informations comme ceci:

Network 10.x.xx.xxx : Online   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.x : Online   
Network 139.xxx.x.x : Online   
Network 208.xx.xxx.xxx : Online   
Network 193.xxx.xxx.x : Online

que je voudrais nettoyer pour obtenir quelque chose comme ça:

Network 10.x.xx.xxx       : Online  
Network 10.x.xx.xxx       : Offline   
Network 10.x.xx.xxx       : Offline    
Network 10.x.xx.x         : Online    
Network 139.xxx.x.x       : Online  
Network 208.xx.xxx.xxx    : Online    
Network 193.xxx.xxx.x     : Online  
Network 193.xxx.xxx.xxx   : Offline
31
pijaaa

Utilisez printf pour formater la sortie (c'est aussi plus portable que echo ). Je voudrais également stocker la valeur réelle des séquences d'échappement de couleur au lieu de les stocker sous une forme qui nécessite une expansion de echo.

RED=$(tput setaf 1) GREEN=$(tput setaf 2) YELLOW=$(tput setaf 3)
NC=$(tput sgr0) 
online="${GREEN}online$NC" offline="${RED}offline$NC"

ping -c 1 "$hostname" > /dev/null 2>&1 && state=$online || state=$offline
printf 'Network %-15s: %s\n' "$hostname" "$state"

%-15s Est une spécification de format qui remplit les chaînes avec des espaces à droite afin que la longueur (en nombre de caractères dans zsh et fish et octets dans la plupart autres shells/printf ) pour être au moins 15.

$ printf '|%-4s|\n' a ab abc abcd abcde
|a   |
|ab  |
|abc |
|abcd|
|abcde|
 printf '|%4s|\n' a ab abc abcd abcde
|   a|
|  ab|
| abc|
|abcd|
|abcde|

Avec troncature:

$ printf '|%.4s|\n' a ab abc abcd abcde
|a|
|ab|
|abc|
|abcd|
|abcd|
$ printf '|%4.4s|\n' a ab abc abcd abcde
|   a|
|  ab|
| abc|
|abcd|
|abcd|
$ printf '|%-4.4s|\n' a ab abc abcd abcde
|a   |
|ab  |
|abc |
|abcd|
|abcd|

D'autres utilitaires pour formater le texte dans les colonnes incluent POSIX expand :

printf 'Network %s\t: %s\n' "$hostname" "$state" | expand -t 30

(développez ici le caractère TAB (\t) avec des tabulations toutes les 30 colonnes)

Ou BSD column ou POSIX pr :

printf 'Network %s\n: %s\n' "$hostname" "$state" | pr -at2

(ici, sortie sur 2 colonnes de 36 colonnes de large (voir l'option -w pour changer la largeur de page par défaut de 72)).

ou BSD rs :

{
   while...
      printf 'Network %s\n: %s\n' "$hostname" "$state"
   done
} | rs -e 0 2

(comme column ne commencera la sortie qu'après avoir lu toutes les entrées).

Ou GNU columns :

printf 'Network %s\n: %s\n' "$hostname" "$state" | columns -w 25 -c 2

zsh a également quelques drapeaux d'extension de paramètre pour le remplissage de chaîne: ${(l:15:)hostname} pour gauche le remplissage et ${(r:15:)hostname} pour remplissage à droite (avec troncature). Dans Expansion d'invite (comme dans les invites ou dans print -P Ou comme activé dans les extensions de paramètres avec le drapeau %), il prend également en charge %F{green} pour la sortie couleur, vous pouvez donc faire:

online='%F{green}online%f'
printf '%s\n' "Network ${(r:15:)hostname}: ${(%)online}"

Ou:

print -rP "Network ${(r:15:)hostname}: $online"

Bien que le contenu de $hostname Serait alors également soumis à une expansion rapide, ce qui constituerait une vulnérabilité d'injection de commande si le contenu de $hostname N'était pas sous votre contrôle (comme dans hostname='%<a[`reboot`]<' )

47

Simplement avec la commande column:

yourscript.sh | column -t

Le résultat:

Network  10.x.xx.xxx     :  Online
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.x       :  Online
Network  139.xxx.x.x     :  Online
Network  208.xx.xxx.xxx  :  Online
Network  193.xxx.xxx.x   :  Online
37
RomanPerekhrest

Mettez à jour votre script pour insérer un numéro défini sur \t (onglets) où vous souhaitez accéder à une colonne.

Produire quelque chose de similaire à ce qui suit vous donnerait l'alignement requis:

Network 10.x.xx.xxx\t: Online   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.x\t: Online   
Network 139.xxx.x.x\t: Online   
Network 208.xx.xxx.xxx\t: Online   
Network 193.xxx.xxx.x\t: Online
3

Pour afficher encore mieux que @Roman

yourscript.sh | column -t -s $'\t'

Puis ajouter \t dans chaque ligne pour le diviser en colonne.

0
Emidomenge