为什么“script”命令会生成^ [和^ M个字符,以及如何使用vimsearch和replace它们?

在Linux上,使用bash shell,当我使用脚本命令时,生成的文件被称为打字稿。 当我用vim打开这个文件时,每一行都包含^ M字符,并且有几行(由于我的彩色命令提示符)包含一个字符^ [ 。 我想用什么都replace这些字符,有效地从生成的脚本中删除它们。

首先,我试过:%s/^[//gc:%s/\^[//gc:%s/\^\[//gc和其他一些变体。 没有一个匹配^ [字符,所以search/replace不起作用。

我也尝试了所有这些与^ M字符相同的结果。 一些谷歌search后,我发现^ M字符是真正的回车“\ r”。 所以然后我试过:%s/\\r//gc ,这对^ M字符有效!

我search了一些,试图找出^ [字符是什么,但没有发现任何帮助。

2个问题

1)什么是[字符,什么是适当的正则expression式在vim中使用来search和replace它?

2)为什么在linux上使用脚本命令时,生成的脚本在行尾产生^ M ? 这使得我认为linux脚本命令正在生成CRLF eol字符,而不仅仅是LF eol字符。

^M^[是控制字符。 正如您已经正确指出的那样,它们是一个字符,而不是两个,您可以在vim中键入它们,方法是按Ctrl+V ,然后Ctrl+[以获得^[

所以你正在寻找的替换命令看起来像s/^[//gc ,唯一的区别是你已经尝试,你不能键入^[字面意思。

^M是一个CR (回车符)。 像dos2unix这样的命令摆脱这些字符。 而且vim还有一些内置函数来摆脱它们。

^[另一方面,是一个颜色控制字符。 在bash中你可能会得到一个彩色输出,在vi​​m中你只能看到控制字符。

事实上,我使用script时看到的是相同的控制字符。 其他人指出,这种行为是预料之中的,我无法找到一个直截了当的方式来规避它,所以我写了一个包装脚本:

 #!/usr/bin/env bash ### Set the variable typescript to the last positional parameter passed to script typescript="${!#}" ### If the last positional parameter is an option (and starts with "-"), ### set typescript to "typescript" (standard argument of script) if [[ "${!#:0:1}" == "-" ]]; then typescript="typescript" fi ### Invoke /usr/bin/script with all options passed to the wrapper script /usr/bin/script $@ ### Once script has finished, call dos2unix to get rid of control characters dos2unix "$typescript" 

将这些行写入一个名为script的文件中,并把它放在/usr/bin之前的$PATH变量中(在我的例子中是~/bin )。 如果你现在键入type script ,它应该指向你的包装脚本,而不是/usr/bin/script 。 当你现在键入script ,它将调用封装脚本,该脚本又调用/usr/bin/scriptdos2unix

为什么在linux上使用脚本命令时,生成的脚本会在行尾产生^ M。 这使得我认为linux脚本命令正在生成CRLF eol字符,而不仅仅是LF eol字符。

因为这是终端驱动程序插入的内容 :

它是规范模式下的终端驱动程序,在伪终端的“内部”,即将NLs扩展到CRNL对。

我发现有些文件是针对不同的行结尾编写的。 Unix,Dos和Mac。 您可以通过以下文件格式重新编辑文件来更改VIM的方式。 我发现^ M在用mac格式编辑时会变成换行符,所以在VIM中运行它。 这不是一个真正的搜索和替换,但有时系统需要文件在特定的行结束如此改变,可能不聪明。

 :e ++ff=mac 

然后你将能够看到这个文件应该看起来如何。

对于其他文件格式相似

 :e ++ff=dos :e ++ff=unix 

当您在Windows上编写脚本并将脚本移植到Linux机器上时, ^M字符出现在行尾。 要删除这个^M字符,可以使用linux build in命令dos2unix ,如下所示:

 dos2unix script_name 

这将删除脚本中的所有^M字符。 我没有测试过^[但是我确定它可以用于删除^M

命令

 sed '/[[:cntrl:]].../s///g ; /[[:cntrl:]]/s///g' typescript > typescript2 

对我来说工作得很好