Ausrichtung der Ausgabe von Bash Shell-Skripten

29

Mein Drehbuch:

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

Gibt Informationen wie folgt aus:

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

was ich gerne aufräumen würde, um so etwas zu bekommen:

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
pijaaa
quelle

Antworten:

45

Verwenden Sie printfzum Format ausgegeben (es ist auch mehr tragbar alsecho ). Ich würde auch den tatsächlichen Wert der Farbfluchtsequenzen speichern, anstatt sie in einer Form zu speichern, die eine Erweiterung um erfordert 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"

%-15sist eine Formatspezifikation, die die Zeichenfolgen mit Leerzeichen auf der rechten Seite auffüllt, sodass die Länge (in Anzahl der Zeichen in zshund fishund Bytes in den meisten anderen Shells / printf ) mindestens 15 beträgt .

$ 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|

Mit Kürzung:

$ 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|

Andere Dienstprogramme zum Formatieren von Text in Spalten umfassen POSIXexpand :

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

(hier das TAB-Zeichen ( \t) mit Tabulatoren alle 30 Spalten erweitern)

Oder BSDcolumn oder POSIXpr :

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

(hier Ausgabe auf 2 Spalten mit einer -wBreite von 36 Spalten (siehe die Option zum Ändern der Seitenbreite von der Standardeinstellung 72)).

oder BSDrs :

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

(Wie columnstartet die Ausgabe erst, wenn alle Eingaben gelesen wurden).

Oder GNUcolumns :

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

zshAußerdem gibt es einige Parametererweiterungsflags für das Auffüllen von Zeichenfolgen: ${(l:15:)hostname}für das Auffüllen von links und ${(r:15:)hostname}für das Auffüllen von rechts (mit Kürzung). Bei der sofortigen Erweiterung (wie in Eingabeaufforderungen oder in print -Poder wie in Parametererweiterungen mit dem %Flag aktiviert ) wird auch die %F{green}Farbausgabe unterstützt , sodass Sie Folgendes tun können:

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

Oder:

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

Der Inhalt von $hostnameunterliegt dann jedoch ebenfalls einer sofortigen Erweiterung, die eine Sicherheitsanfälligkeit in Bezug auf Befehlsinjektion darstellt, wenn der Inhalt von $hostnamenicht unter Ihrer Kontrolle steht (wie in hostname='%<a[`reboot`]<').

Stéphane Chazelas
quelle
35

Einfach mit columnBefehl:

yourscript.sh | column -t

Die Ausgabe:

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
RomanPerekhrest
quelle
Es tut mir leid für dumme Frage, aber wo soll ich diesen Befehl setzen?
pijaaa
@ Pijaaa, siehe mein Update, Pipeline mit Ihrer Skriptausgabe
RomanPerekhrest
10
Beachten Sie, dass column(ein BSD-Befehl, der ebenfalls auf Linux portiert ist und in einigen Distributionen standardmäßig vorkommt, nicht mit GNU zu verwechseln columns) die gesamte Eingabe gelesen werden muss, bevor mit der Ausgabe begonnen werden kann, da die Breite der Spalten berechnet werden muss auf der breitesten.
Stéphane Chazelas
3

Aktualisieren Sie Ihr Skript, um eine festgelegte Nummer in \t(Tabulatoren) einzufügen, in die Sie eine Spalte auslagern möchten.

Wenn Sie etwas Ähnliches wie das Folgende ausgeben, erhalten Sie die erforderliche Ausrichtung:

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
djsmiley2k - CoW
quelle
3
Es lohnt sich, ein kurzes Beispiel basierend auf dem Skript in der Frage hinzuzufügen ...
Stephen Kitt
@StephenKitt ty Stephen, ich habe versucht herauszufinden, wie ich es mehr als nur eine Zeile machen kann, und das ist mir ehrlich gesagt nicht eingefallen!
djsmiley2k - CoW
3
Sie werden feststellen, dass mit den Standard-Tabulatoren alle 8 Spalten printf 'Network %s\t: Online\n' 8.8.8.8 192.168.122.123nicht richtig ausgerichtet wird. Sie können expanddas umgehen , indem Sie die Registerkarten mit einem anderen Tabstopp erweitern, wie in meiner Antwort gezeigt.
Stéphane Chazelas
Bitte akzeptieren Sie dies als Antwort, indem Sie auf das Häkchensymbol klicken.
djsmiley2k - CoW
0

Um noch besser als @Roman anzuzeigen

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

Fügen Sie dann \tjede Zeile hinzu, um sie in Spalten aufzuteilen.

Emidomenge
quelle