ANSI 이스케이프 코드를 사용하여 문자열 정렬

ANSI 이스케이프 코드를 사용하여 문자열 정렬

설정된 옵션 색상이 녹색이고 설정되지 않은 옵션 색상이 빨간색인 모든 zsh 옵션의 정렬된 목록을 인쇄하려고 합니다. 그러나 sort컬러 라인에서는 작동 하지 않습니다 . 다음은 모든 빨간색 옵션을 인쇄한 다음 모든 녹색 옵션을 인쇄합니다.

print -lP "%F{green}"${^$(setopt)} "%F{red}"${^$(unsetopt)} | sort

각 옵션 줄이 빨간색과 녹색 print -P으로 시작하도록 형식 문자열이 확장되었기 때문인 것 같습니다 . 보고 있다^[[31m^[[32msort맨페이지, 도움이 될 수 있는 두 가지 옵션이 있습니다.

-i, --ignore-nonprinting 인쇄 가능한 문자만 고려

-k, --key=POS1[,POS2] POS1(시작점 1)에서 키를 시작하고 POS2(기본 줄 끝)에서 끝납니다.

그래서 나는 다음을 시도한다:

print -lP "%F{green}"${^$(setopt)} "%F{red}"${^$(unsetopt)} | sort -i

그리고

print -lP "%F{green}"${^$(setopt)} "%F{red}"${^$(unsetopt)} | sort --key=<N>

<N>다양한 숫자를 설정해 보았습니다 . 모든 경우에 동일한 결과를 얻습니다(모든 빨간색 옵션이 녹색보다 먼저 옵니다). 이 문제를 어떻게 해결할 수 있나요?

답변1

-k정렬 옵션은 필드와 문자라는 두 개의 숫자 인수를 사용합니다. 첫 번째 필드의 6번째 문자를 기준으로 정렬하려고 합니다. %F{green}교체된 이후 6번째 문자입니다 ESC[32m. 그래서 이것은 작동합니다 :

print -lP "%F{green}"${^$(setopt)} "%F{red}"${^$(unsetopt)} | sort -k 1.6

답변2

와 같은 이스케이프 시퀀스에서 ^[[31m이스케이프 문자 ^[는 인쇄할 수 없는 문자이지만 다른 문자 [31m는 인쇄 문자입니다. 따라서 sort -i도움이 되지 않습니다. 이스케이프 문자는 무시하지만 여전히 [31mred[0m이전에 정렬됩니다 [32mgreen[0m.

유틸리티에 내장된 기능 이상의 기준에 따라 데이터를 정렬하는 일반적인 방법 sort은 각 행의 데이터를 두 배로 늘리고 첫 번째 복사본이 정렬 키가 되도록 처리한 다음 행을 정렬하고 마지막으로 첫 번째 부분을 제거하는 것입니다. 예를 들어, 정렬하려는 데이터에 탭 문자가 포함되어 있지 않다고 가정합니다.

awk '{s=$0; gsub(/\033\[[ -?]*[@-~]/,"",s); print s "\t" $0}' |
sort |
awk 'BEGIN {RS="\t"} {print $2}'

관련 정보