【问题标题】:Bash - How to get string length exclude escape characterBash - 如何获取字符串长度排除转义字符
【发布时间】:2015-05-25 17:32:38
【问题描述】:

我在 ~/.bashrc 中写了一个函数来根据当前终端宽度绘制一条水平线。

p_blod=$(tput bold) #use p_orig to reset it
p_red=$(tput setaf 1) #print red
p_blue=$(tput setaf 21) #print blue
p_yellow=$(tput setaf 11) #print yellow
p_orig=$(tput sgr0) #print back original color

vzone() { 
        : "${3?"Usage : vzone '='(separator) y/b(color) b(bold)/nb(not blod) [separator_length_if_need_exclude_escape]"}" #\space or \( 

        local vzone_sep="$1"

        if [[ -z $4 ]]; then
                local t_cols=${#vzone_sep}  #only if the string didn't included escape characters
        else
                local t_cols="$4"
        fi
        
        if [[ "$3" == "b" ]]; then
                printf "%s" "${p_blod}"
        fi

        if [[ "$2" == "y" ]]; then
                printf "%s" "${p_yellow}"
        else
                printf "%s" "${p_blue}"
        fi

        eval printf %.0s"$vzone_sep" $(seq 1 "$((COLUMNS/t_cols))"); echo

        printf "%s" "${p_orig}"
}

然后调用者画一条线:

vzone '\(◔‿◔\)\ ♥' y b 7

截图:

如您所见,如果我没有手动计算放入 7,则该行将出错,因为 ${#vzone_sep} 将给我包含转义字符斜杠/ 的总字符串p>

让我展示一个狭窄的例子:

[xiaobai@xiaobai tmp]$ vzone_sep="\(◔‿◔\)\ ♥"
[xiaobai@xiaobai tmp]$ printf ${#vzone_sep}
10[xiaobai@xiaobai tmp]$

我想要的是 7,而不是包含转义字符的 10。因此调用者不必在调用我的函数之前手动计算长度减去转义字符。

感谢您的帮助。

【问题讨论】:

  • 不使用eval(并且不将转义字符放入字符串)会更简单。为什么你觉得你需要eval
  • @rici 因为我不能在没有转义字符的情况下调用我的函数,例如vzone '(◔‿◔) ♥' y b 将在意外标记 `(' 附近抛出语法错误
  • 你可以不使用转义字符调用函数如果你不使用eval
  • @rici 感谢您指出,因为最初我没有使用 seq,而是按照本教程进行操作,wiki.bash-hackers.org/snipplets/print_horizontal_line。但是因为当时我不太了解 ${COLUMNS:-$(tput cols)}" 的东西,所以我改用 seq。我没有意识到 eval 不再需要,也不需要转义。谢谢。

标签: bash shell escaping


【解决方案1】:
vzone_sep="\(◔‿◔\)\ ♥"
cleaned="${vzone_sep//\\/}"  # remove all \
printf "%d" "${#cleaned}"

输出:

7

【讨论】:

    猜你喜欢
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 2013-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多