gpt4 book ai didi

bash - 在 bash 中选择菜单

转载 作者:行者123 更新时间:2023-12-04 14:34:44 26 4
gpt4 key购买 nike

出于某种原因,我的菜单呈现如下:

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 来自文件:

readarray -t entries < ./file

文件的内容是原始文本数据:

option 1
option 4
option leg
option arm
option whatever
option blabla

所以 select block 是这样的:

select opt in "${MENU_OPTIONS[@]}" "${entries[@]}";
do
case "$opt" in
...)
;;

最佳答案

Bash 主要计算每个选项中的字符,无论它们是否“可显示”。因此,用于突出显示您的某些项目的转义码会误显示。

这是一个例子:

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 混合使用 tab空格缩进各种选项)

无论如何,这在我的系统上正常显示:

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 个字符。与各种转义码中的字节数不匹配。

但是,给定来自 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 字符...

关于bash - 在 bash 中选择菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24726958/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com