代码之家  ›  专栏  ›  技术社区  ›  Tom Hale

转义\[和\]之间非打印字符的ANSI序列

  •  0
  • Tom Hale  · 技术社区  · 6 年前

    这个 bash manual 表示在提示中,任何非打印字符的序列都应包含如下内容: \[this\] :

    \[  Begin a sequence of non-printing characters.
        This could be used to embed a terminal control sequence into the prompt.
    
    \]  End a sequence of non-printing characters.
    

    如果提示中包含一个字符串,如何自动转义所有ANSI控制/颜色代码,以便在所有情况下正确显示/换行提示?


    区别:这里我假设已经生成了一个包含ANSI控制代码的字符串。

    This related question 假设可以通过编辑字符串的生成函数插入分隔符。

    2 回复  |  直到 6 年前
        1
  •  0
  •   Tom Hale    6 年前

    下面将把ANSI控制序列用ASCII括起来 SOH ( ^A ) STX ( ^B ) which are equivalent to \[ and \] respectively :

    function readline_ANSI_escape() {
      if [[ $# -ge 1 ]]; then
        echo "$*"
      else
        cat  # Read string from STDIN
      fi | \
      perl -pe 's/(?:(?<!\x1)|(?<!\\\[))(\x1b\[[0-9;]*[mG])(?!\x2|\\\])/\x1\1\x2/g'
    }
    

    使用方法如下:

    $ echo $'\e[0;1;31mRED' | readline_ANSI_escape
    

    或:

    $ readline_ANSI_escape "$string"
    

    另外,多次运行该函数不会重新转义已经转义的控制代码。

        2
  •  0
  •   that other guy    6 年前

    不要试图使之自动化。

    为什么bash要求您添加 \[...\] 因为shell不能合理地知道任何给定的终端如何解释任何转义代码,所以手工操作。如果是的话,巴什一开始就会这么做。

    例如,下面是其他答案无法处理的许多情况中的一些。在每种情况下,在我的特定终端上都没有输出,但转义函数无法转义它们:

    printf '\e]1;Hello\a'  # Set window title
    printf '\e[0;2;0;0;0}' # 24-bit color
    printf '\e[13]'        # Unblank screen