Wie kann ich mit dem in Bash integrierten „printf“ eine Ausgabe in Spalten durchführen, wenn die Quelle Farben enthält?

Wie kann ich mit dem in Bash integrierten „printf“ eine Ausgabe in Spalten durchführen, wenn die Quelle Farben enthält?

Der Code lautet:

#!/bin/bash
ips[0]='192.168.0.1'
ips[1]='192.168.0'
ips[2]='255.255.255.256'
ips[3]='123.123.123.123.123'
ips[4]='a.b.c.d'
ips[5]='255.255.255.255'
ips[6]='0.0.0.0'
ips[7]='192.168.1.1'
ips[8]='4.2.2.2'

regex="^((25[0-5]|2[0-4][0-9]|[01][0-9][0-9]|[0-9]{1,2})[.]){3}(25[0-5]|2[0-4][0-9]|[01][0-9][0-9]|[0-9]{1,2})$"

regexVar=$(printf "\033[33mSaved in a VARIABLE\033[0m")
regexStr=$(printf "\033[34mIs a STRING\033[0m")
validOut=$(printf "\033[32mValid\033[0m")
invalidOut=$(printf "\033[31mInvalid\033[0m")
noQuotes="NO quotes"
singleQuotes="Single quotes"
doubleQuotes="Double quotes"

printStyle="%-25s %-10s %-20s %-10s\n"
printTitle=$(printf "${printStyle}" "IP Address" "Validity" "Regex" "Quote Type")
print2ndLine=$(printf "${printStyle}" "====================" "==========" "====================" "==========")

function validIP1a() {
    echo "${printTitle}"
    echo "${print2ndLine}"
    for (( i=0; i<${#ips[@]}; i++ )); do
        if [[ "${ips[i]}" =~ $regex ]]; then
            printf "${printStyle}" "${ips[i]}" "${validOut}" "${regexVar}" "${noQuotes}"
        else
            printf "${printStyle}" "${ips[i]}" "${invalidOut}" "${regexVar}" "${noQuotes}"
        fi
    done
}

validIP1a

Die Ausgabe ist:

Ausgabe kann nicht ausgerichtet werden

Die erwartete Ausgabe ist:

erwartete ausgerichtete Ausgabe

Warum erziele ich nicht das erwartete Ergebnis? Wie kann ich das Problem lösen?

Antwort1

Weil printfes die Zeichen im Escape-Code zählt, der die Farbe festlegt, weiß es nicht, dass sie nicht tatsächlich gedruckt werden. Sie müssten sie außerhalb der formatierten ( %-20s)-Zeichenfolgen mit fester Länge platzieren. Vergleichen Sie die beiden printfs hier:

#!/bin/bash
green=$'\033[32m'
yellow=$'\033[33m'
normal=$'\033[0m'

printf "1234567890123456789012345678901234567\n";
printf "%-20s %s\n" "${yellow}some string${normal}"  "next col"
printf "${yellow}%-20s${normal} %s\n" "some string"  "next col"

Die Ausgabe sollte folgendermaßen aussehen:

Beispielausgabe

Wenn sich die Farbe ändern kann, können wir sie natürlich in eine andere Variable einfügen:

printf "%s%-20s${normal} %s\n" "$green" "some string"  "next col"

Antwort2

Möglicherweise möchten Sie die Zeichen in validOutund zählen invalidOut. Ich zähle in jedem davon mehr als 10:

#                                11   11111
#                    1   2245678901   23456
  validOut=$(printf "\033[32mValid\033[0m")
invalidOut=$(printf "\033[31mInvalid\033[0m")

Bedenken Sie, dass Arme printfunmöglich wissen können, dass einige dieser Zeichen unsichtbar sind und Farbänderungen bewirken ... Sie haben ein linksbündiges Feld mit mindestens 10 Zeichen angefordert und es dann mit Zeichenfolgen mit mehr als 10 Zeichen gefüllt; kein Wunder, dass das Ergebnis nicht vertikal ausgerichtet ist.

verwandte Informationen