소스에 색상이 포함된 경우 Bash 내장 `printf`를 사용하여 열 단위로 출력하려면 어떻게 해야 합니까?

소스에 색상이 포함된 경우 Bash 내장 `printf`를 사용하여 열 단위로 출력하려면 어떻게 해야 합니까?

코드는 다음과 같습니다

#!/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

출력은 다음과 같습니다

출력을 정렬할 수 없습니다.

예상되는 출력은 다음과 같습니다.

일관된 결과물 기대

왜 예상한 결과를 얻을 수 없나요? 어떻게 해결하나요?

답변1

색상을 설정하는 이스케이프 코드의 문자를 계산하기 때문에 printf실제로 인쇄되지 않는다는 것을 알 수 없습니다. %-20s고정 길이 format() 문자열 외부에 배치해야 합니다 . 여기에서 두 가지를 비교하십시오 printf.

#!/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"

출력은 다음과 같아야 합니다.

샘플 출력

물론 색상을 변경할 수 있다면 이를 다른 변수에 넣을 수 있습니다.

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

답변2

validOut합계에서 문자 수를 세고 싶을 수도 있습니다 invalidOut. 저는 문자 수를 세었고 각각 10개가 넘습니다.

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

가난한 사람이 이러한 문자 중 일부가 보이지 않고 색상이 변한다는 것을 알 수 있는 방법이 없습니다 printf... 최소 10자의 왼쪽 정렬 필드를 요청한 다음 계속해서 10보다 긴 문자열로 채웁니다. 문자; 결과가 수직으로 정렬되지 않은 것은 당연합니다.

관련 정보