为什么 "script" 命令会生成 ^[ 和 ^M 字符以及如何使用 vim 搜索和替换来删除它们?



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

首先,我尝试了:%s/^[//gc:%s/^[//gc:%s/^[//gc和其他一些变体。它们都与 ^[ 字符不匹配,因此搜索/替换不起作用。

我还尝试了 ^M 字符的所有这些变体,结果相同。经过一番谷歌搜索,我发现^M字符实际上是回车符"\r"。所以后来我尝试了:%s/\r//gc,这对^M字符有效!

我用谷歌搜索了一些,试图弄清楚 ^[ 字符是什么,但没有发现任何有用的东西。

2个问题

1) ^[ 字符是什么,在 vim 中使用什么合适的正则表达式来搜索和替换它?

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

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

因此,您正在寻找的替换命令看起来像 s/^[//gc ,与您尝试的唯一区别是您无法按字面意思键入^[

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

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

事实上,我在使用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 查看这些内容的方式。 我发现在以 mac 格式编辑时 ^M 会更改为换行符,因此请在 VIM 中运行它。 这不是真正的搜索和替换,但是有时系统需要文件位于特定行结尾,因此更改这可能并不明智。

:e ++ff=mac

然后,您将能够看到此文件的外观。

对于其他文件格式,其类似

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

命令

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

对我来说效果很好

当您

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

dos2unix script_name

这将从脚本中删除所有^M字符。我还没有测试过它^[但我确信它可以去除^M.

最新更新