bash: 从带有 ANSI 代码的字符串中发出 n 个可打印字符

bash: Emit n printable characters from a string with ANSI codes

bash 中,给定一个包含 ANSI CSI codes(例如颜色)的任意字符串,我如何发出可打印字符的子集,以正确的颜色打印?

例如,给定:

s=$'\e[0;1;31mRED\e[0;1;32mGREEN\e[0;1;33mYELLOW'

我该怎么做:

coloursubstr "$s" 0 5 

coloursubstr "$s" 2 7 

部分答案,(带有幻数的特定 hack,一点也不笼统):

echo "${s:0:23}"
echo "${s:0:9}${s:11:25}"

输出:

使用 bash 和 GNU grep:

coloursubstr() {
  local string="" from="" num=""
  local line i array=()

  # fill array
  while IFS= read -r line; do
    [[ $line =~ ^([^m]+m)(.*)$ ]]
    for ((i=0;i<${#BASH_REMATCH[2]};i++)); do
      array+=("${BASH_REMATCH[1]}${BASH_REMATCH[2]:$i:1}")
    done
  done < <(grep -Po $'\x1b.*?m[^\x1b]*' <<< "$string")

  # print array
  for ((i=$from;i<$from+$num;i++)); do
    printf "%s" "${array[$i]}"
  done
  echo
}

s=$'\e[0;1;31mRED\e[0;1;32mGREEN\e[0;1;33mYELLOW'

coloursubstr "$s" 0 5
coloursubstr "$s" 2 7

输出:


我假设所有颜色代码都以 \e 开头,以 m 结尾,并且文本以颜色代码为前缀。