Vim 运行 shell 命令将汉字转换为符号 '?'

Vim runs shell command turning Chinese character into sign '?'

我试过运行set .*encoding(例如,encodingfileencoding等)变成utf-8,但问题不是解决了。​​

问题是:当我运行正常命令时shell,一切顺利:

$ make SQL
+-----+-----------+------------------+-------+
| Sno | Sname     | Cname            | Grade |
+-----+-----------+------------------+-------+
| 01  | Peter     | C Language       |  98.1 |
| 01  | Peter     | Data Struct      |  89.3 |
...
| 08  | 王小明    | NULL             |  NULL |
| 09  | 王明儿    | NULL             |  NULL |
| 10  | A明B      | NULL             |  NULL |
| 11  | A明B      | NULL             |  NULL |
...
+-----+-----------+------------------+-------+

它运行良好,但是当我在 vim 下使用 vim-command :r!make SQL 运行 它时,它会打印 '?'符号:

+-----+-----------+------------------+-------+
| Sno | Sname     | Cname            | Grade |
+-----+-----------+------------------+-------+
| 01  | Peter     | C Language       |  98.1 |
| 01  | Peter     | Data Struct      |  89.3 |
...
| 08  | ???       | NULL             |  NULL |
| 09  | ???       | NULL             |  NULL |
| 10  | A?B       | NULL             |  NULL |
| 11  | A?B       | NULL             |  NULL |
...
+-----+-----------+------------------+-------+

我不确定会发生什么,但我有一个可行的解决方案:

  1. 运行 make SQL > tmp 在 shell.
  2. 运行 :r!cat tmp 在 vim.

我也知道 :r!make SQL > tmp && cat tmp 仍然有 '?'问题。我确实想在 vim 中直接使用 r!make SQL,这就是我问这个问题的原因。感谢您的帮助。

:r!locale的结果是:

locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=en
LANGUAGE=
LC_CTYPE="en"
LC_NUMERIC="en"
LC_TIME="en"
LC_COLLATE="en"
LC_MONETARY="en"
LC_MESSAGES="en"
LC_PAPER="en"
LC_NAME="en"
LC_ADDRESS="en"
LC_TELEPHONE="en"
LC_MEASUREMENT="en"
LC_IDENTIFICATION="en"
LC_ALL=

en 在许多系统上都不是有效的语言环境,即使在接受的地方,它也不会得到您想要的结果。通常,语言环境的格式为 xx_XX.CHARSET,其中 xx 是语言代码,XX 是国家代码,CHARSET 是字符集。例如,您可以为使用 UTF-8 的美式英语编写 en_US.UTF-8,或者为使用 UTF-8 的瑞士法语编写 fr_CH.UTF-8

因为大多数 Unix 操作系统早于 UTF-8 存在(macOS 是一个可能的例外),通常系统上的默认区域设置不是 UTF-8,因此如果您指定未声明 UTF- 8 明确表示,您的工具将不会使用 UTF-8。

因此,您需要按照上述格式适当地设置区域设置,以便您的系统在任何地方都使用 UTF-8。这将使程序正确运行。

特别是 Vim,如果您从这样的管道命令读取数据,Vim 将进行字符集检测(由 fileencodings 控制)。如果您没有设置 encoding 并且您的语言环境是 Unicode 语言环境,Vim 将查找字节顺序标记,然后是 Unicode,然后默认为 latin1。如果它不是 Unicode 语言环境并且未设置该值,那么 Vim 将只是您当前的语言环境,这可能会被解释为 latin1,您会很伤心。这看起来像这里发生的事情。

当然,您可以调整 encodingfileencodingfileencodings,但在 Vim 和所有程序中获得正常行为的最简单方法是将您的语言环境设置为使用 UTF-8 的语言环境。