灵感来自这个问题,我可以使用该iconv
命令生成带有 BOM 和指定字节顺序的 UTF-16 输出吗?
该iconv
命令将文本从一种编码转换为另一种编码。
例如:
echo hello | iconv -f ascii -t utf-16
生成 的 UTF-16 表示形式"hello\n"
。
UTF-16 文件通常(但并非总是)以字节顺序标记 (BOM) 开头,它是 Unicode 字符 的 2 字节编码U+FEFF
。您可以通过检查前两个字节是否为FE FF
或来确定带有 BOM 的 UTF-16 文件的字节顺序FF FE
。
该iconv
命令有多个用于生成 UTF-16 输出的选项:
$ iconv --list | grep -i utf-16
UTF-16//
UTF-16BE//
UTF-16LE//
此命令:
echo hello | iconv -f ascii -t utf-16be
生成大端 UTF-16无物料清单;它似乎假设如果您指定了字节序,则无需在输出中指明它。同样,utf-16le
生成没有 BOM 的小端 UTF-16。
这:
echo hello | iconv -f ascii -t utf-16
在我的 x86 Ubuntu 系统上生成 little-endian UTF-16和BOM——但我已经看到过一份报告称,即使在小端系统上,类似的命令也会生成带有 BOM 的大端 UTF-16。
我总是可以使用utf-16be
或utf-16le
并手动添加 BOM,但我正在寻找仅使用命令的解决方案iconv
。
另一种解决方法,如果您知道字节序-t utf-16
会产生什么吗?是:
echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null
我想喜欢使用方法是这样的:
iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM
但iconv
不支持这一点。
编辑 :
有权访问 x86 Mac OSX 系统的人可以发表评论并显示以下命令的(复制粘贴的)输出吗?
echo hello | iconv -f ascii -t utf-16 | od -x
答案1
不,如果指定字节顺序,iconv
则不会插入 BOM。
这是来自Unicode 联盟
问:我应该如何处理 BOM?
答:请遵循以下指导原则:
- 特定协议(例如 Microsoft 的 .txt 文件约定)可能要求在某些 Unicode 数据流(例如文件)上使用 BOM。当您需要遵守此类协议时,请使用 BOM。
- 某些协议允许在未标记文本的情况下使用可选的 BOM。在这些情况下,
- 如果已知文本数据流是纯文本,但编码未知,则可以使用 BOM 作为签名。如果没有 BOM,则编码可以是任何内容。
- 如果已知文本数据流是纯 Unicode 文本(但不知道其字节序),则可以使用 BOM 作为签名。如果没有 BOM,则应将文本解释为大端文本。
- 一些面向字节的协议要求文件开头有 ASCII 字符。如果在这些协议中使用 UTF-8,则应避免使用 BOM 作为编码形式签名。
- 如果知道数据流的精确类型(例如 Unicode 大端或 Unicode 小端),则不应使用 BOM。特别是, 每当数据流被声明为 UTF-16BE、UTF-16LE、UTF-32BE 或 UTF-32LE BOM一定不使用。
(我强调)
我希望iconv
尝试忠实于这些准则中的最后一条。
更新。
题外话
在我看来:
指定 BOM 的选项对于 iconv 来说无疑是一个有用的附加功能。
无 BOM 的 UTF-16LE 文件是适用于 Windows,但有时需要付出更多努力。例如,记事本的“文件打开”对话框允许您选择“Unicode”,这是 Microsoft 为“UTF-16LE”起的名字,并且(不出所料)似乎适用于没有 BOM 的文件。
我可以在 Windows 记事本 (XP) 中以通常的方式打开 UTF-16LE 测试文件(无 BOM)或 UTF-8 测试文件(无 BOM),例如在资源管理器中双击文件名。这对我来说似乎很有用。我知道有时 Windows 会错误地猜测编码 - 在这种情况下,您必须在打开文件时告诉记事本编码。这种不便意味着对于打算在 Windows 上使用的文本文件,最好包含 BOM。
如果特定应用程序不能处理除带有 BOM 的 UTF-16LE 文件之外的任何文件,那么我同意不带 BOM 的 UTF-16LE 文件不适用于该特定应用程序。
我怀疑如果您可以使一切使用 UTF-8(无 BOM)工作,这是长远来看最好的解决方案。
然而,这个问题的答案是“我可以使用 iconv 命令生成带有 BOM 和指定字节顺序的 UTF-16 输出吗?“ 目前 ”不“。
答案2
如果要将 BOM 添加到文件,您可以手动添加:
对于 UTF-8 BOM(EF BB BF)
file='main.cpp'
printf '\xEF\xBB\xBF' > $file.utf8
iconv -f ASCII -t UTF-8 $file >> $file.utf8
mv -v $file.utf8 "converted-$file"
对于 UTF-16BE BOM(FE FF)
file='main.cpp'
printf '\xFE\xFF' > $file.utf16be
iconv -f ASCII -t UTF-16BE $file >> $file.utf16be
mv -v $file.utf16be "converted-$file"
对于 UTF-16LE BOM(FF FE)
file='main.cpp'
printf '\xFF\xFE' > $file.utf16le
iconv -f ASCII -t UTF-16LE $file >> $file.utf16le
mv -v $file.utf16le "converted-$file"
笔记:
您可能注意到每种情况下的 BOM 都不同。您可以找到更多信息请点击此处: