我有几个 C++ 源文件(一个 .cpp 和一个 .h)被报告为类型数据通过file
Linux 中的命令。当我file -bi
针对这些文件运行该命令时,我得到了以下输出(每个文件的输出相同):
application/octet-stream; charset=binary
每个文件都是纯文本(我可以在 中查看它们vi
)。是什么原因导致file
错误报告这些文件的类型?可能是某种 Unicode 问题吗?这两个文件都是在 Windows 环境中创建的(使用 Visual Studio 2005),但它们是在 Linux 中编译的(它是一个跨平台应用程序)。
任何想法,将不胜感激。
更新:我在两个文件中都看不到任何空字符。我在 .cpp 文件(在注释块中)中找到了几个扩展字符,删除了它们,但file
仍然报告相同的编码。我尝试在 SlickEdit 中强制编码,但似乎没有效果。当我在 中打开文件时vim
,我一打开文件就看到一行[converted]
。也许我可以让 vim 强制编码?
答案1
Vim 会尽力理解你输入的内容,而不会发出任何抱怨。这使得它成为诊断file
输出的相对较差的工具。
Vim 的“[converted]”通知表示文件中有一些内容是 vim 不希望在您的语言环境设置(LANG 等)建议的文本编码中看到的内容。
其他人已经建议
cat -v
xxd
您可以尝试查找非 ASCII 字符。
grep -P '[\x7f-\xff]' filename
另一种可能性是平台的非标准行尾(即 CRLF 或 CR),但我希望file
应对这种情况并报告“DOS 文本文件”或类似内容。
答案2
我使用二进制搜索来定位有问题的行,从而发现了问题。
head -n {1/2 line count} file.cpp > a.txt
tail -n {1/2 line count} file.cpp > b.txt
对每一半进行运行file
并重复该过程,帮助我找到了有问题的行。我发现其中嵌入了一个Control+ P( ^P
) 字符。删除它解决了问题。我将为自己编写一个 Perl 脚本来搜索这些字符(和其他扩展字符)。
非常感谢所有为所有提示提供答案的人!
答案3
如果您运行file -D filename
,file
将显示调试信息,包括它执行的测试。在接近尾声时,它将显示哪些测试在确定文件类型方面是成功的。
对于常规文本文件,它看起来像这样:
[31> 0 regex,=^package[ \t]+[0-9A-Za-z_:]+ *;,""]
1 == 0 = 0
ascmagic 1
filename.txt: ISO-8859 text, with CRLF line terminators
这将告诉您它发现了什么以确定它是那个 mime 类型。
答案4
它可以这些文件是在开头以 BOM 形式保存的,尽管我原以为文件二进制的最新版本也应该能识别这一点。
您是否尝试过通过“head -2 | xxd”之类的方法转储它们并查看是否存在 BOM?
*BOM = 字节顺序标记 - 有时出现在 unicode 文本文件中。 http://en.wikipedia.org/wiki/Byte_order_mark