使用 for 循环模仿 select 语句在添加颜色时输出不均匀的列

Using a for loop to imitate a select statement outputs uneven columns when colors added

我有一个超过 100 个元素的数组。我需要一个菜单​​来列出这些元素,然后我需要 select 这些元素之一以便在脚本中进一步使用。很简单..

select opt in "${menu[@]}"; do
    case $REPLY in
        [0-9]*) # do stuff with $opt
    esac
done

但据我所知,除了 $COLULMN 宽度之外,似乎无法自定义 select 输出菜单的方式。所以我想我会使用 for 循环来模仿 select 并为菜单添加一点颜色。

#!/usr/local/bin/bash

bold(){
    printf '%b' "3[38;1m$@3[0m"
}

mapfile -t options < <(gshuf -n50 /usr/share/dict/words)
n=${#options[@]}
i=0

until [[ $i -eq $n ]]; do
    for opt in "${options[@]}"; do
        i=$((i+1))
        bold "$i) "
        echo "$opt"
    done
done | column

这确实允许我为菜单着色,但它也弄乱了列结构

例如,这是没有颜色的样子

1) sowt                 40) priorate            79) Arakanese
2) pachysomia           41) poudrette           80) mesenchyma
3) somnivolency         42) magnifice           81) deconsideration
4) gargoyle             43) cautionry           82) meliorable

这就是颜色的样子

1) sowt  40) priorate           79) Arakanese
2) pachysomia           41) poudrette           80) mesenchyma
3) somnivolency         42) magnifice           81) deconsideration
4) gargoyle             43) cautionry           82) meliorable

有人能告诉我为什么会这样吗?有没有办法在不破坏 columns/formatting 等的情况下简单地为编号列表的数字着色? select 可以做到这一点吗?那将是理想的。

似乎 column 命令不知道转义序列在输出中没有 space,但您可以使用 sed 在 [=12 之后添加序列=]命令,例如:

shuf -n 50 /usr/share/dict/words \
 | nl -nln -s") " -w1 \
 | column \
 | sed "s/[0-9]\+/$(tput bold)&$(tput sgr0)/g"

或者:

shuf -n 50 /usr/share/dict/words \
 | nl -nln -s") " -w1 \
 | column -c $COLUMNS \
 | sed "s/[0-9]\+/$(tput bold)&$(tput sgr0)/g"