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

bash:从带有ANSI代码的字符串中发出n个可打印字符,bash,ansi-escape,Bash,Ansi Escape,在bash中,给定包含(例如颜色)的任意字符串,如何发出以正确颜色打印的可打印字符子集 例如,给定: s=$'\e[0;1;31mRED\e[0;1;32mGREEN\e[0;1;33mYELLOW' 我该如何做以下事情: coloursubstr "$s" 0 5 部分答案(特定的魔法数字破解,完全不是一般的): 输出: 使用bash和GNU grep: coloursubstr() { local string="$1" from="$2" num="$3" local

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

例如,给定:

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

我该如何做以下事情:

coloursubstr "$s" 0 5 

部分答案(特定的魔法数字破解,完全不是一般的):

输出:


使用bash和GNU grep:

coloursubstr() {
  local string="$1" from="$2" num="$3"
  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
colorsubstr(){
本地字符串=“$1”from=“$2”num=“$3”
本地行i数组=()
#填充数组
当IFS=读取-r行时;执行
[[$line=~^([^m]+m)(.*$]]

对于((i=0;我想在!@TomHale问这个问题,同样地,请重新阅读
部分
非…一般
。虽然上述问题不是令人满意的答案,但它可能是第一步或跳板想法,它的工作原理可能对某些读者有用。
echo "${s:0:23}"
echo "${s:0:9}${s:11:25}"
coloursubstr() {
  local string="$1" from="$2" num="$3"
  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