RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 861575
Accepted
Ole Lukøje
Ole Lukøje
Asked:2020-07-29 04:05:20 +0000 UTC2020-07-29 04:05:20 +0000 UTC 2020-07-29 04:05:20 +0000 UTC

使用 Unicode Box Drawing 中的字符在 bash 中构建框架

  • 772

我想以某种方式安排 Bashevsky 脚本,以便它在一个漂亮的框架中给出一个菜单。我在谷歌上搜索,抓挠我的萝卜,嗯,然后冲掉了几个小功能。结果,我很高兴地与 SO 参与者分享,突然间它会派上用场。

linux
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Ole Lukøje
    2020-08-01T00:31:00Z2020-08-01T00:31:00Z

    这是发生的事情:

    declare -A C # Массив значений цветов
    def_colors ()
    {
        C[Black]='\e[30m'
        C[Red]='\e[31m'
        C[Green]='\e[32m'
        C[Yellow]='\e[33m'
        C[Blue]='\e[34m'
        C[Magenta]='\e[35m'
        C[Cyan]='\e[36m'
        C[LGray]='\e[37m'
    
        C[Default]='\e[39m'
    
        C[DGray]='\e[90m'
        C[LRed]='\e[91m'
        C[LGreen]='\e[92m'
        C[LYellow]='\e[93m'
        C[LBlue]='\e[94m'
        C[LMagenta]='\e[95m'
        C[LCyan]='\e[96m'
        C[White]='\e[97m'
    
        C[Normal]='\e[0m'
    }
    
    draw_line ()
    {
        local position="$1"
        local width_line="$2"
        local repeat="$4"
        local left_position="$3"
        local line_simbol='\u2501'
        local line left_indent spacer
    
        [[ $width_line -ne 0 ]] && spacer="\e[${width_line}C"
        [[ $left_position -ne 0 ]] && left_indent="\e[${left_position}C"
    
        case "$position" in
            --top)
                left_corner='\u250F'
                right_corner='\u2513'
                ;;
            --bottom)
                left_corner='\u2517'
                right_corner='\u251B'
                ;;
            --blank)
                left_corner='\u2503'
                right_corner='\u2503'
                ;;
            --box-separator)
                left_corner="\u2523"
                right_corner="\u252B"
                ;;
        esac
    
        if [[ "$position" == '--blank' ]]; then
            while read -r;do
                line+="${left_indent}${left_corner}${spacer}${right_corner}\n"
            done < <(seq "$repeat")
            printf '%b' "$line"
        else
            while read -r;do
                line+="$line_simbol"
            done < <(seq "$width_line")
            printf '%b%b%b%b\n' "${left_indent}" "$left_corner" "$line" "$right_corner"
        fi
    }
    
    draw_frame ()
    {
    
        local footer_height frame_color frame_height frame_width
        local top_position left_position restore_position start_write
    
        local terminal_width
            terminal_width=$(tput cols)
        local terminal_hight
            terminal_hight=$(tput lines)
    
        until [[ "$#" -eq 0 ]]; do
            case "$1" in
                -t) if [[ "$2" =~ ^[0-9]+$ ]];then
                        if [[ "$2" -lt "$(( terminal_hight - 5 ))" ]];then
                            top_position="$2"
                        else
                            top_position="$(( terminal_hight - 5 ))"
                        fi
                        shift
                    else
                        if [[ -z "$2" ]]; then
                            top_position=0
                        else
                            echo 'Set a positive numeric value for the top position of frame'
                        fi
                    fi
                    ;;
                -l) if [[ "$2" =~ ^[0-9]+$ ]];then
                        if [[ "$2" -lt "$(( terminal_width - 2 ))" ]];then
                            left_position="$2"
                        else
                            left_position="$(( terminal_width - 2 ))"
                        fi
                        shift
                    else
                        if [[ -z "$2" ]]; then
                            left_position=0
                        else
                            echo 'Set a positive numeric value for the left position of frame'
                        fi
                    fi
                    ;;
                -w) if [[ "$2" =~ ^[0-9]+$ ]];then
                        if [[ "$2" -lt "$(( terminal_width - 2 ))" ]];then
                            frame_width="$2"
                        else
                            frame_width="$(( terminal_width - 2 ))"
                        fi
                        shift
                    else
                        echo 'Set a positive numeric value for the frame width'
                        tput cnorm
                        return 1
                    fi
                    ;;
                -h) if [[ "$2" =~ ^[0-9]+$ ]];then
                        if [[ "$2" -lt "$(( terminal_hight - 5 ))" ]];then
                            frame_height="$2"
                        else
                            frame_height="$(( terminal_hight - 5 ))"
                        fi
                        shift
                    else
                        echo 'Set a positive numeric value for the frame height'
                        tput cnorm
                        return 1
                    fi
                    ;;
                -c) if [[ "$2" =~ \\e\[[0-9]{1,2}m$ ]]; then
                        frame_color="$2"
                        shift
                    else
                        [[ "$2" ]] &&
                        {
                            [[ "$2" =~ ^- ]] || shift
                        }
                    fi
                    ;;
                -f) if [[ "$2" =~ ^[0-9]+$ ]];then
                        footer_height="$2"
                        shift
                    else
                        [[ "$2" ]] &&
                        {
                            [[ "$2" =~ ^- ]] || shift
                        }
                        footer_height=1
                    fi
                    ;;
                -r|--restore-position)
                    restore_position='1'
                    ;;
                -s|--start-write)
                    start_write='1'
                    ;;
            esac
            shift
        done
    
        top_position=${top_position:-0}
        left_position=${left_position:-0}
    
        [[ "$start_write" ]] && restore_position=
        [[ "${restore_position:-0}" -eq 1 ]] && tput sc # Сохраняем позицию курсора
    
        tput civis
        clear
    
        tput cup "$top_position" 0
        if [[ $(( frame_width + left_position )) -gt $(( terminal_width - 2 )) ]];then
            frame_width=$(( terminal_width - left_position - 2 ))
        fi
        if [[ $(( frame_height + top_position )) -gt $(( terminal_hight - 5 )) ]];then
            frame_height=$(( terminal_hight - top_position - 5 ))
        fi
    
        [[ "$frame_color" ]] && printf '%b' "$frame_color"
        if [[ "$frame_width" ]] && [[ "$frame_height" ]]; then
            draw_line --top "$frame_width" "$left_position"
            draw_line --blank "$frame_width" "$left_position" "$frame_height"
            [[ -n "$footer_height" ]] && \
                draw_line --box-separator "$frame_width" "$left_position" && \
                    draw_line --blank "$frame_width" "$left_position" "$footer_height"
            draw_line --bottom "$frame_width" "$left_position"
        fi
        [[ "$frame_color" ]] && printf '%b' '\e[0m'
    
        [[ "${restore_position:-0}" -eq 1 ]] && {
                tput rc # Восстановить позицию
    
                }
    
        [[ "$footer_height" ]] && (( footer_height++ ))
        [[ "${start_write:-0}" -eq 1 ]] && \
            printf '%b' \
                "\\e[$(( frame_height + 1 + ${footer_height:-0} ))A\\e[$(( left_position + 1 ))C"
    
        tput cnorm
    }
    

    -w 帧宽度;
    -h 帧高度不包括页脚;
    -c 框架颜色;
    -f 页脚高度;

    高度和宽度分别是行数和字符数,可以在不钩框架本身的情况下输入

    如果你省略 -f,那么只会有一个没有页脚的框
    如果你省略 -c,那么边框的颜色将是你终端的标准

    draw_frame -w 50 -h 20 -c ${C[Green]} -t 5 -l 5 -f 1
    

    所有尺寸分别在终端的列和行中。

    UPD 改进
    了一点,现在可以设置框相对于终端左上角的位置:

    -l 左移
    -t 下移

    一个好处。添加了两个选项:

    -r [--restore-position] - 将光标返回到绘图开始之前的位置
    -s [--start-write] - 将光标设置到空帧字段的左上角

    bash unicode 绘图框

    • 8

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5