如何将 DOS ANSI (CP 437) 文件转换为带有 Unicode 的 Unix ANSI?

Posted

技术标签:

【中文标题】如何将 DOS ANSI (CP 437) 文件转换为带有 Unicode 的 Unix ANSI?【英文标题】:How do I convert DOS ANSI (CP 437) files to Unix ANSI with Unicode? 【发布时间】:2013-12-17 15:41:43 【问题描述】:

http://blocktronics.org/ 的 ANSI 文件似乎使用了另一种 ANSI 编码,而不是我的 VT100 终端仿真器支持的编码。

如果我使用tetraview 查看这些文件,它们看起来不错。但是,如果我使用less -r 查看它们,则块字符不起作用。如果我使用iconv -f 437 -t utf-8 | less -r,块字符可以工作,但字符的对齐仍然是混乱的。它在tetraview 中工作,所以一定有某种转换正在进行。

我写了一个脚本来抓取在tmux 中运行的tetraview 的屏幕内容,但这是一个hack,我想做tetraview 自己做的转换。

【问题讨论】:

您能否澄清对齐仍然混乱的意思?另外,您在什么系统上运行 iconv? @zatch_rulz:iconv 正在 Ubuntu Saucy 上运行。当我说对齐搞砸时,我的意思是:i.imgur.com/Lf0RF1u.png 右边是 tetraview,左边是 iconv 输出。两个终端都是 80x24。截图中的文件是来自 ACiD Trip 的dman-warrior.ANS 只是为了给未来的读者节省一些时间:tetraview 是Tetradraw 的一部分。 【参考方案1】:

涉及两个问题

编码 需要从CP 437 转换为您的终端编码。正如您已经发现的那样,这是使用 iconv -f 437 input_file.ANS 完成的。 ANSI escape sequences 需要修复。

dman-warrior.ANS 中使用了两个types of escape sequences。第一个只使用一次,是文件中的第一件事。它是ESC[0m,它会重置所有图形模式属性。第二种类型是ESC[<value>C(例如ESC[24C),它将光标<value>字符向前(向右)移动。如果光标不能继续前进,它就会停止。您可以使用以下 shell 命令在终端中对其进行测试:

printf '\x1b[10000CXYZ\n'

应该是这样的:

|$ printf '\x1b[10000CXYZ\n'              |
|                                        X|
|YZ                                       |
|$                                        |

图像文件只有几行(由 CRLF 分隔)。每个都被包裹到终端宽度(80 列),从而产生几条屏幕线。

图像在文件行中间以ESC[<value>C 转义序列开头的第一行之前都可以。

终端写入上一个屏幕行,在最后一列结束。 满足ESC[<value>C 转义序列。由于位于最后一列,光标不能再向右移动,因此序列被忽略。 接下来是一个字符,它强制换行并打印在下一个屏幕行上。

新的屏幕行缺少应该被转义序列跳过的空白区域。

可能的解决方案

以某种方式改变终端仿真器的行为。 (我不知道怎么做,除了编译一个经过调整的自定义版本。) 明确换行。如果ESC[<value>C 是唯一使用的转义序列,那么编写一个修复图像的程序应该很容易。

【讨论】:

【参考方案2】:

这些文件都是“动画”类型,它依赖于特定的屏幕宽度和高度来显示它。您的终端可能没有正确的宽度。

【讨论】:

我的终端的标准尺寸为 80x24。由于这也是 DOS 的标准宽度,并且 tetraview 成功地在这样的终端中显示图像,我认为这不是问题。【参考方案3】:

Littleimp 的回答有些正确。

许多 ANSI 艺术作品专为比当前标准 80 列更宽的终端尺寸设计。 Janus 认为这种艺术仅适用于 80 列是不正确的。仔细的目视检查会发现,有些用户每行使用的字符要多得多。

与大多数标准文本文件不同,许多 ANSI 艺术文件 /not/ 包含 CR 或 CR/LF 来终止每一行的结尾,而是允许终端为它们换行到下一行。这使他们可以使用终端的完整列,例如80 或 132,无需在行尾前进行 CRLF,使最大宽度为 79 或 131。

所以例如blocktronicks goo-b7.ans 将无法在 160 个字符宽之外的任何终端中正确显示。

我在此处的 ANSI 图片示例中对此进行了说明: https://i.imgur.com/WBJ8xfs.png

在每个 X 字符后插入回车的标准 sed/awk 技巧将不起作用,因为不会跳过以 CR/LF 结尾的短行,而是在插入 CR 之前从下一行的长度中减去在不合适的地方。

要将这些文件转换为更合理的文件,需要一个程序/脚本来逐行执行,仅在找到具有最大行长的行时插入 CR。

【讨论】:

【参考方案4】:

我在网上找了一个你不需要安装的自动转换器。 http://www.gofunnow.com/convertutf8/convertutf8.php?destencoding=-2#.UqdmkifMrAk

【讨论】:

那个站点使用了“ANSI”的另一种定义,他们可能只是指CP-1251。无论如何,这比 iconv 没有任何优势。

以上是关于如何将 DOS ANSI (CP 437) 文件转换为带有 Unicode 的 Unix ANSI?的主要内容,如果未能解决你的问题,请参考以下文章

求C++代码,把ANSI编码的.txt(中文内容的)文件转成成utf-8编码格式的文件

VS2008 控制台DOS界面的代码页中文怎么改英文?

如何实现UTF-8 Unicode Ansi 汉字编码转换

jar文件如何从utf-8转ansi?

请问用批处理命令如何将ANSI编码的txt文件批量转换utf8编码的?就右键另存为那种,但是量太大。

如何将csv文件转换成Ansi编码的文件?