cmd 文本最后一行_echo与ANSI控制码结合:富文本编辑

9f3ebe2652a4cf7731638bf5ec8b1b60.png

引言

无论学习什么编程语言,所接触到的第一个例子必然是打印Hello World!,在bash当中这个例子是通过如下方式实现的:

echo "Hello World!"

它的输出结果是:

2e177a0ea2c0ddad53b8486d927aab90.png
bash版Hello World

现在有一个非常有趣的问题就是,如果我想要打印出红色的字体该怎么整呢?

在继续说明echo如何实现这一目标之前,先简要介绍一下我的bash环境:

  • Microsoft Windows [版本 10.0.19041.113] (Windows预览体验计划)
  • Ubuntu-18.04 WSL version 2
  • Windows Terminal (Preview)
  • GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)

echo基础用法

echo的作用就是将文本打印到终端,其基本用法就是在echo后面添上你想要打印出来的语句,如前文的Hello World例子。

echo可以接受多个参数,打印的时候会用单个空格将参数们隔开,比如:

c0d14515a658c098c1a2bc4bf5fca4c3.png
单个空格隔开传给echo的参数

原本以为会打印出Hello World的例子,实际上打印出来的还是Hello World,这是因为echoHelloWorld视为两个参数。要想真正打印出Hello World,需要使用双引号将字符串包起来,使之成为单个参数,如下所示:

9db2b8b4d312aa3611f7a65121c3d992.png
双引号的作用

在bash当中,单引号和双引号的作用是不相同的。单引号的表现有点像python当中的r'<string>',双引号的则有点像python当中的f'{<var_name>}' 。举个简单的例子就能看明白了:

9df438e3376f1e871c37f3aa504d9055.png
单引号与双引号的对比

单引号直接原样打印了包含在其中的字符串,双引号则会先将变量转化成其对应的字符串,然后再进行打印。

事实上,在使用echo的时候完全可以不带引号,本小节开篇的第一张图就是一个很好的例子。但是强烈建议带上引号,不带引号可能会让程序出现一些难以预料的后果。比如:

2eb452665fc6c37f1ca5a971ae04827a.png
不带引号可能会出现一些难以预料的后果

你以为输出的内容会带上好几个空格,但实际上只有一个空格出现。所以比较好的习惯就是,但凡使用echo输出内容,就给挂上双引号。

带选项的echo

echo其实还有几个选项可以使用的,使用man echo 就可以发现echo可以接受5个不同的选项,分别是-n, -e, -E, --help, --version。这几个选项的含义其实也是非常好记的。--help自然是打印出echo的帮助文档,--version用来查看当前echo的版本号。

默认情况下,echo打印完文本后就会自动跳到下一行,加上-n这个选项以后,echo就会把光标停在原地了,不会自动跳转到下一行,可见示例:

6a4788e69320f8608edc7e297a15a38b.png
选项-n让echo不会自动跳转到下一行

默认情况下, echo是不会接受转义字符的,只有带上了-e的选项,转义字符才会被解释成相应的内容,可见示例:

88184e95c4e85ea62b30b2db0e5171d1.png
-e选项用来控制转义字符的输出与否

-E这个选项的含义就和-e反过来了,就是转义字符一律都不要打印出来,可见示例:

fcec56d07deb0dc0afae9d4929aa07de.png
-E选项屏蔽所有的转义字符

echo的手册当中能够看到所有支持的转义字符,详见下图:

e37a6ed6cc66dbbbb0fd97bad2d7d919.png
常见的几个转义字符

还有两个用的非常多的转义字符,分别是', ",显然这两个转义字符就是为了能够输出单引号和双引号而设计的。

echo的富文本编辑

整了老半天了,怎么还是没有看到富文本编辑? ——@匿名知乎网友

在上一小节的最后一张图里面,我们看到了几个不常见的转义字符,其中的e就是我们的主角了。 它和ANSI控制码的配合就可以实现我们的富文本编辑了。

简单来说,ANSI控制码就是一些已经定义好了的特殊转义字符。它们都以ESC [开头,然后后面放上一些看着像乱码一样的东西,就能够实现一些特殊的功能了。

先来看看字体颜色的设置吧。ANSI控制码中可以控制字体的前景色与背景色,它的格式是

e[<foreground-color code>;<background-color code>m

代码中的e显然就是ESC的转义符,ESC [意味着我们要开始整ANSI控制码了,foreground-color codebackground-color code都是已经定义好了的一些常量,照着拿来用就好了,最后要挂上一个m,完成整条语句。先看示例:

3db8490ac79cd70f508f9a40f715610c.png
ANSI控制码初体验

这里面有一个小问题,那就是这个白色底太长了,我们不想要它这么长的。在输出完想要输出的内容以后,我们再清除先前设定的所有格式 就行了,要用到的代码是e[0m,可见示例:

75ca6653d2c271a1a881891f20b89151.png
设置完格式后再取消格式设置

如果我们只要设置其前景色或者是背景色,只要把相应的代码和分号去掉就可以了。可见示例:

91c44609c81f9b7fd39c4dd586fbd928.png
只改前景色或背景色

现在列出所有可用的前景色代码和后景色代码:

0136d6b48f6f89a95c2d699ba45c432e.png
基本的前景色代码和后景色代码

不难看出前景色以3或9开头,从0排到7,后景色以4或10开头,从0排到7,对应的颜色其实是相同的。这里总共给出了16种颜色,如果我们还想要更加丰富的颜色可该咋整呢?

我们还可以使用256色,相应的转义字符如下:

e[38;5;<fore-ground code>me[48;5;<back-ground code>m

给一个具体的实例:

a7ff108e7a7163b9f2954673bdcca6d9.png
256色使用示例

这里面的前景色代码和后景色代码的取值范围是[0, 255],具体的颜色示例可见下图:

e4c5c41262581797eede015c0ddfad98.png
256色颜色列表(来源:维基百科)

对于我的ThinkPad X201i来说,只能够显示256种颜色还是太屈才了,起码得支持RGB全色域才行嘛。在自己的终端支持的情况下,我们是可以使用RGB颜色的。

相应的转义字符如下:

e[38;2;<r>;<g>;<b>me[48;2;<r>;<g>;<b>m左边是前景色,右边是背景色

给一个简单的示例就行了:

c57b05dfbaaa88d86c0fac158dc40b77.png
RGB颜色使用示例

关于颜色的设置知道这么多就绰绰有余了,更多的内容可以去翻阅维基百科。

除了设置字体的颜色以外,我们还可以对字体的样式进行一些简单的设置:

  • 加粗:e[1m
  • 下划线: e[4m
  • 反色显示: e[7m

d8395c9037603f58ad49046f2901fbe5.png
简单的使用示例,加粗有点翻车

ANSI控制码实现对光标的控制

ANSI控制码可以实现对光标的控制,比如:

  • 向上移动光标n行:e[nA
  • 向下移动光标n行:e[nB
  • 向右移动光标n列:e[nC
  • 向左移动光标n列:e[nD

这里移动光标的时候如果触及到了边界,就不会再移动了。使用这里的ANSI控制码,就可以实现一个非常简单的进度条了。每次输出完内容后,禁止换行,并且将光标挪到最左边,然后继续输出。

for index in {1..100} ; do
    echo -ne "e[999D${index}%"
    sleep 0.05
done
echo

4407a86b31e337ed8c25b1a0ef2d6232.gif
使用ANSI控制符实现的简易进度条
  • 隐藏光标,e[?25l 注:在我的Windows Terminal上面没有用,但在cmd里面有用
  • 显示光标,e[?25h
  • 保存光标位置,e[s
  • 恢复上一次保存的光标位置,e[u
  • 将光标移动到下n行的头,e[nE
  • 将光标移动到上n行的头,e[nF
  • 设置光标位置,e[n;mH,n代表行,m代表列
  • 清屏,e[nJ
    • 当n=0时,清除光标到屏幕结尾的所有内容 ;
    • 当n=1时,清除光标到屏幕开始的所有内容;
    • 当n=2时,清除所有内容
  • 清除当前行内容,e[nK
    • 当n=0时,清除光标到行尾所有内容;
    • 当n=0时,清除光标当行首的所有内容;
    • 当n=2时,清除光标所在行的所有内容

小结

更多内容留待后续补充

参考文献

Build your own Command Line with ANSI escape codes

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值