색상 코드가 printf를 xterm 테이블 형식으로 엉망으로 만듭니다.

색상 코드가 printf를 xterm 테이블 형식으로 엉망으로 만듭니다.

제가 작업 중인 스크립트는 여러 열로 구성된 색상 표를 표시하지만 색상 코딩이 서식 지정을 방해합니다. 일부 열의 색상은 행마다 다르기 때문에 색상 코드를 형식 문자열로 이동할 수 없습니다. 관련 Q&A(아래 참조)에는 해결 방법이 나와 있지 않습니다. 아래에 간단한 예와 해결 방법을 제공했습니다.

내 실제 사용법은 여러 개의 jpg 파일을 반복하고 다양한 EXIF ​​데이터를 구문 분석하고 결과를 테이블의 행으로 출력하는 동안 생성된 서로 다른 색상의 서로 다른 열이 있는 11개의 열 테이블을 표시하는 bash 스크립트입니다. EXIF 분석 결과에 따라 정렬된 행과도 다릅니다.

하지만 앞서 말했듯이 아래에 간단한 해결 방법 예를 제공했습니다.

다음은 문제를 보여주는 단순화된 표시 테이블 조각입니다.

# RedBlk defined in .bashrc.local as RedBlk="^[[0;31;40m"
# DefDef defined in .bashrc.local as DefDef="^[[0m"
(GrnBlk=$(tput setaf 2)
 YelBlk="\e[1;33m"
 echo "123456789 123456789"
 for ii in {8..13}; do
 case $ii in
   8|9) clr1=""; clr2="";;
    11) clr1=$RedBlk; clr2="";;
    12) clr1=$YelBlk; clr2=$GrnBlk;;
     *) clr1=$GrnBlk; clr2=$RedBlk;;
  esac
  printf "%6d %6b$DefDef %6b\n"   $((ii*2))   $clr1$ii    $clr2$((ii*4)) 
done)

....산출:

123456789 123456789
    16      8     32
    18      9     36
    20 10 40
    22 11     44
    24 12 48
    26 13 52

"^[[0;31;40m"또는를 사용하면 $(tput setaf 2)동일한 문제가 발생할 수 있습니다 ."\e[1;33m"

이는 지나치게 단순화된 예입니다.

(echo "123456789 123456789 123456789"
 printf "%20s\n" "Hello""Again"
 printf "%20s\n" $RedBlk"Hello"$DefDef"Again"
)

....산출:

123456789 123456789 123456789
          HelloAgain
HelloAgain

두 가지 솔루션1) 필드 너비를 변경하고(예: 지나치게 단순화된 예에서는 =에서 =로 20) 2) 문자열을 분할하고 형식을 수정합니다.20+${#RedBlk}+${#DefDef}20+10+4

(echo "123456789 123456789 123456789"
 printf "%20s\n"       "Hello""Again"
 printf "%34s\n"       $RedBlk"Hello"$DefDef"Again"
 printf "%s%15s%s%s\n" $RedBlk "Hello" $DefDef "Again"
)

....산출:

123456789 123456789 123456789
      HelloAgain
      HelloAgain
      HelloAgain

그러나 실제 사용을 고려하면 두 솔루션 모두 매우 서투릅니다.

다음 Q&A는 관련이 있지만 해결책을 제공하지는 않습니다.

https://stackoverflow.com/questions/67638971/how-to-get-color-and-width-formatting-with-printf

https://stackoverflow.com/questions/58519511/bash-printf-formated-output-with-colors

https://stackoverflow.com/questions/5412761/using-colors-with-printf

색상 코드가 있을 때 printf와 %s를 어떻게 사용합니까?

더 간단한 해결책은 무엇입니까?

이것이 내가 사용하는 것입니다:

bash --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)

# which printf
/usr/bin/printf
# /usr/bin/printf --version
printf (GNU coreutils) 8.26

# /usr/bin/xterm -version
XTerm(327)

답변1

한 가지 해결책은 다음과 같이 루프가 반복될 때마다 형식 문자열을 동적으로 생성하는 것입니다.

 fmt=`printf  "%b"  "%6d "$clr1"%6d$DefDef "$clr2"%6d"$DefDef`
 printf "$fmt\n"   $((ii*2))   $ii    $((ii*4)) 

가득한:

(DefDef=$(tput init)
 RedBlk=$(tput setaf 1)
 GrnBlk=$(tput setaf 2)
 YelBlk="\e[1;33m"
 echo "123456789 123456789"
 for ii in {8..13}; do
 case $ii in
   8|9) clr1=""; clr2="";;
    11) clr1=$RedBlk; clr2="";;
    12) clr1=$YelBlk; clr2=$GrnBlk;;
     *) clr1=$GrnBlk; clr2=$RedBlk;;
 esac
 fmt=`printf  "%b"  "%6d "$clr1"%6d$DefDef "$clr2"%6d"$DefDef`
 printf "$fmt\n"   $((ii*2))   $ii    $((ii*4)) 
done)

....산출:

123456789 123456789
    16      8     32
    18      9     36
    20     10     40
    22     11     44
    24     12     48
    26     13     52

답변2

또 다른 해결책은 각 필드를 동일한 길이 COLOR_ON(color)COLOR_OFF시퀀스( color보통 black)로 둘러싸는 것입니다. 이 정도까지 작업하세요.

관련 정보