出于某种原因,我的菜单呈现如下:
1) RUNTHROUGH 6) option 4
2) QUIT 7) option leg
3) NEW SEARCH PATERN 8) option arm
4) CLEAR SEARCHES 9) option whatever
5) option 1 10) option blabla
,但我希望它能够正确对齐,如下所示:
1) RUNTHROUGH 6) option 4
2) QUIT 7) option leg
3) NEW SEARCH PATERN 8) option arm
4) CLEAR SEARCHES 9) option whatever
5) option 1 10) option blabla
我该怎么做?
我从两个数组中填充菜单:
一个是由像这样的标签变量构建的:
MENU_OPTIONS=( "$SCRIPT_RUNTHROUGH" "$PROGRAM_QUIT" "$PATTERN_NEW" "$PATTERN_CLEAR" )
其中变量具有这样的值,带有颜色转义
SCRIPT_RUNTHROUGH=$'\e[1;31mRUNTHROUGH\e[0;33m'
PROGRAM_QUIT=$'\e[1;31mQUIT\e[0;33m'
PATTERN_NEW=$'\e[1;31mNEW SEARCH PATERN\e[0;33m'
PATTERN_CLEAR=$'\e[1;31mCLEAR SEARCHES\e[0;33m'
另一个数组entries
来自file:
readarray -t entries < ./file
file
的内容是原始文本数据:
option 1
option 4
option leg
option arm
option whatever
option blabla
所以select
块就像:
select opt in "${MENU_OPTIONS[@]}" "${entries[@]}";
do
case "$opt" in
...)
;;
答案 0 :(得分:3)
Bash主要计算每个选项中的char,无论它们是&#34;可显示&#34;或不。因此,用于突出显示某些项目的转义代码会错误显示。
以下是一个例子:
sh$ for i in {1..12}; do OPTIONS[$i]=$(printf "option-%02d" $i); done
sh$ select i in "${OPTIONS[@]}"; do echo $i ; done
1) option-01 4) option-04 7) option-07 10) option-10
2) option-02 5) option-05 8) option-08 11) option-11
3) option-03 6) option-06 9) option-09 12) option-12
这是预期的。但如果我突出第4项:
sh$ OPTIONS[4]=$'\e[1;31moption-04\e[0;33m'
sh$ select i in "${OPTIONS[@]}"; do echo $i ; done
1) option-01 4) option-04 7) option-07 10) option-10
2) option-02 5) option-05 8) option-08 11) option-11
3) option-03 6) option-06 9) option-09 12) option-12
解决方法强>
嗯......它更像是一种破解而不是一种解决方法。真。
我在每个选项的末尾添加一些额外的空格以扩大列。相反,我在突出显示的选项的末尾添加了一些\b
(6在我的测试中给出了很好的结果)。我不能更精确,因为我无法清楚地确定要遵循的规则。您可能必须准备好进行反复试验...
(事情更复杂的事实Bash
使用标签和的混合空格缩进各种选项)
无论如何,这在我的系统上正确显示:
sh$ for i in {1..12}; do OPTIONS[$i]=$(printf "option-%02d " $i); done
# ^^^^^^^^
sh$ OPTIONS[4]=$'\e[1;31moption-04\e[0;33m\b\b\b\b\b\b'
# ^^^^^^^^^^^^
sh$ select i in "${OPTIONS[@]}"; do echo $i ; done
1) option-01 5) option-05 9) option-09
2) option-02 6) option-06 10) option-10
3) option-03 7) option-07 11) option-11
4) option-04 8) option-08 12) option-12
编辑:我对我的例子中的事实感到困惑,菜单被8个字符关闭了。与各种转义码中的 bytes 的数量不匹配。
但是,考虑到GNU bash 4.2中的代码:
(execute_cmd.c
)
static int
displen (s)
const char *s;
{
#if defined (HANDLE_MULTIBYTE)
wchar_t *wcstr;
size_t wclen, slen;
wcstr = 0;
slen = mbstowcs (wcstr, s, 0);
if (slen == -1)
slen = 0;
wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (slen + 1));
mbstowcs (wcstr, s, slen + 1);
wclen = wcswidth (wcstr, slen);
free (wcstr);
return ((int)wclen);
#else
return (STRLEN (s));
#endif
}
如果使用多字节支持编译Bash,它会使用mbstowcs
转换原始字符串,以便使用wcswidth
计算其长度。鉴于我的系统有UTF-8 LC_CTYPE,可能mbstowcs
将转义代码错误转换为某些Unicode字符...