在xterm中,我可以关闭粗体或下划线而不重置当前颜色吗?

8
我正在处理输入(来自诸如ls -la --color之类的源)并强调文本的某些部分。我不是逐个字符地处理这些输入,而是使用大量的正则表达式,这使得跟踪我所影响的子字符串是否已经着色或加粗变得相当困难。如果我有一段红色的文本,并且我想要在其中的某个部分下划线,我可能会这样做:
s/(123)/\033[4m\1\033[0m/g

(我的表达更加复杂。实际上,匹配项被提取出来,单独处理,然后进一步分解和分析。这不是通过改变我在这里给出的表达式就能完成的。)
上面的代码将替换所有出现的123为[UNDERLINE_START]123[FORMAT_RESET]。不幸的是,重置也会关闭文本的着色。如果我只想禁用下划线而不影响其他内容,那将为我节省很多麻烦,但我相当确定没有办法做到这一点。有人可以告诉我我错了吗?
编辑:我可以简化问题,问:如果我想关闭下划线,是否可以在不影响当前文本颜色的情况下进行,因为该颜色可能在我的脚本执行之前就已经设置好了,而我没有办法检测到该颜色是什么?
2个回答

12

似乎没有人记录这一点,但将装饰器代码加20将关闭它们:

  echo -e "\\033[34;4m" underlined "\\033[24m" not underlined
  echo -e "\\033[34;1m" bold "\\033[2m" not bold
  echo -e "\\033[34;2m" dark "\\033[22m" not dark
  echo -e "\\033[34;7m" inverse "\\033[27m" not inverse

1
等一下,1怎么变成2了?其他的都按照你加20的规则来。 - mpen
4
2 表示浅色,不表示取消粗体。22 表示取消浅色 粗体。使用 21 取消粗体并不被广泛支持(例如,在 macOS 上没有支持)。 - Rockallite
1
它在ECMA-48:1979中有记录。ECMA-48:1984展示了SGR 21的实际含义。 - JdeBP

4

使用下面的内容替代那些硬编码的转义序列:

tput smul # set underline
tput rmul # remove underline

tput smso # set bold on
tput rmso # remove bold

tput setaf 1 #red
tput setaf 2 #green

...
tput cup 0 0 # move to pos 0,0

参考“man terminfo”和“man tput”获取这些命令的完整描述。
示例:
function f_help
{
c_green=$(tput  setaf 2      2>/dev/null)
c_reset=$(tput  sgr0         2>/dev/null)
c_bold=$(tput smso           2>/dev/null)
echo "${c_bold}DESCRIPTION${c_reset} : ...."
}


echo "${c_green}GREEN ${c_underline} GREEN AND UNDERLINED${c_nounderline} GREEN AGAIN${c_reset} PLAIN BLACK TEXT"

${c_underline}转义序列不影响文本颜色,只会打开下划线。 ${c_nounderline}则是关闭下划线。


2
"smso"(“突出模式”)与“bold”不同。在我的终端(GNOME 终端)上,它会以正常字重进入反向视频模式。 "bold" 将使用 tput bold 命令设置,可通过 tput sgr0 命令重置。 - uncleremus
我试着坚持使用tput,但它只会让事情变得更复杂。例如,在xterm-256color上,tput sgr0返回\e(B\e[m'。第二个转义序列等同于\e0m,即"重置所有模式",但我还没弄清楚\e(B是什么意思。此外,像ls(现在还有exa)这样的标准工具并不关心termcap,而是直接使用ANSI转义序列。 - A. Donda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接