如何在 zsh 中使用字符串修饰符修改输入变量?

如何在 zsh 中使用字符串修饰符修改输入变量?

我一直在开发一个bold函数作为概念验证和对自己的挑战。我正在尝试输入文本(例如foo)并将其打印到标准输出,因为它是粗体对应项(foo)。

语境:

我一直在使用主题文件中的变量echo并将其作为基础。PROMPT我没有使用任何框架。

%B%n%b该主题使用诸如粗体用户名 ( ) 之类的代码%n,但我不知道如何用%n用户输入 ( $1) 替换它。有帮助吗?

编辑:尝试的代码

echo '%B'"$1"'%b'

-在不同位置尝试过带引号和不带引号,以及使用子 shell ( {})

答案1

%B%b是例子提示序列,通常只能用于格式化提示。对于正常的脚本编写,您可以使用以下tput命令来实现您想要的:

echo "$(tput bold)$1$(tput sgr0)"

或者,您可以输出ECMA-48(“ANSI”)直接转义码。但我不推荐这样做,因为它跨终端的便携性较差。 (如今在 21 世纪,遇到不实现 ECMA-48 和基本 ECMA-48 SGR 功能(如粗体)的终端是相当困难的,但既然你正在挑战自己学习这一点,你应该知道终端可以不能保证理解彼此完全相同的控制序列。您还应该了解到,仍然有一些终端模拟器中的粗体是颜色变化而不是字体粗细变化。)

echo $'\e[1m'"$1"$'\e[22m'

注意使用科恩式引用为控制序列。在一般情况下,该echo命令可能会也可能不会本身如果不是 Korn 风格的引用,则解释\e序列,并且此类转义序列在不同的 shell 甚至同一 shell 的不同版本中工作方式不同;相反,并非所有 shell 都能理解 Korn 风格的引用。看 ”为什么 printf 比 echo 更好?对于整个故事,echo如果您要解决除单个特定(版本)shell 之外的任何问题,那么为什么不是一个好主意。

printf '\e[1m%s\e[22m' "$1"

请注意,SGR 0(对应于\e[0m,这tput sgr0也是现在通常发出的)关闭一切,如果您是这样,这可能不是您想要的使用下划线、斜体、颜色、反向视频或其他图形再现。关闭粗体具体来说,SGR 22 是图形呈现代码,它关闭粗体和淡化,恢复“中等”字体粗细。 (这SG拉菲克endition 控制序列允许您设置四种字体粗细:粗体、半粗体、中等和浅色。)

自从你使用 Z shell,您可以使用它自己的内置print命令而不是使用echoprintf根本不使用。可以让内置函数print理解 Z shell 提示符扩展序列:

print -P '%B'"$1"'%b'

当然,您的$1字符串本身不能包含其他扩展序列,也不能包含任何用于更改粗体的 SGR 控制序列。这不会给您带来学习tput以及 terminfo 功能如何工作的挑战。

答案2

%可以使用参数扩展标志:

echo "${(%):-%B}$1${(%):-%b}"

zsh 有一个print内置函数,必须-P执行提示扩展(注意:如果 $1 包含提示序列,它们将被解释为这样):

print -P -- "%B$1%b"

您可能想要打印所有参数,而不仅仅是第一个位置参数(使用$@/ $*)。

如果没有给出参数,您可能不想打印任何内容(甚至不打印换行符)(仅在$#大于零时打印,或使用+参数扩展并告诉print输出列)。

您可能想要禁用反斜杠转义符 ( print -r) 的类似回显的解释。

print_bold() {
  local IFS=' '
  print -rC1 -- ${1+"${(%):-%B}$*${(%):-%b}"}
}

"$*"扩展为由第一个字符分隔的位置参数IFS(默认情况下是空格,但上面已明确设置)。

相关内容