我已将某些文件从Windows计算机复制到Linux计算机。因此,所有Windows编码(windows-1252)文件都需要转换为UTF-8。不应更改已存在UTF-8的文件。我打算使用recode
实用程序。如何指定recode
实用程序应仅转换windows-1252编码文件而不转换UTF-8文件?
重新编码的示例用法:
recode windows-1252.. myfile.txt
这会将myfile.txt
从windows-1252转换为UTF-8。在此之前,我想知道myfile.txt
实际上是windows-1252编码而不是UTF-8编码。否则,我相信这会破坏文件。
答案 0 :(得分:63)
你可以使用iconv:
iconv -f WINDOWS-1252 -t UTF-8 filename.txt
答案 1 :(得分:37)
您希望重新编码知道文件是Windows-1252吗?理论上,我相信任何文件都是有效的Windows-1252文件,因为它将每个可能的字节映射到一个字符。
现在肯定存在强烈建议它是UTF-8的特征 - 例如,如果它以UTF-8 BOM开头 - 但它们不是确定的。
一种选择是首先检测它是否真的是一个完全有效的UTF-8文件,我想......再次,这只是暗示性的。
我不熟悉recode工具本身,但您可能想知道它是否能够从相同的编码重新编码文件 - 如果您使用无效文件执行此操作(即,包含无效的UTF-8字节序列的那个,它可以很好地将无效序列转换成问号或类似的东西。此时,您可以通过将文件重新编码为UTF-8并查看输入和输出是否相同来检测文件是否为有效UTF-8。
或者,以编程方式执行此操作而不是使用重新编码实用程序 - 例如,在C#中它非常简单。
重申一下:所有这些都是启发式的。如果你真的不知道文件的编码,那么没有任何东西可以100%准确地告诉你。
答案 2 :(得分:9)
这是我对类似问题的另一个答案的转录:
如果将utf8_encode()应用于已经是UTF8的字符串,它将返回一个乱码的UTF8输出。
我做了一个解决所有这些问题的函数。它叫做Encoding :: toUTF8()。
您不需要知道字符串的编码是什么。它可以是Latin1(iso 8859-1),Windows-1252或UTF8,或者字符串可以混合使用它们。 Encoding :: toUTF8()会将所有内容转换为UTF8。
我这样做是因为一项服务给了我一个混乱的数据,将UTF8和Latin1混合在同一个字符串中。
用法:
$utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string);
$latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string);
下载:
https://github.com/neitanod/forceutf8
更新
我已经包含了另一个函数Encoding :: fixUFT8(),它将修复每个看起来乱码的UTF8字符串。
用法:
$utf8_string = Encoding::fixUTF8($garbled_utf8_string);
示例:
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
将输出:
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
更新:我已经将函数(forceUTF8)转换为一个名为Encoding的类的静态函数族。新函数是Encoding :: toUTF8()。
答案 3 :(得分:8)
没有通用的方法来判断文件是否使用特定编码进行编码。请记住,编码只不过是一个“协议”,如何将文件中的位映射到字符。
如果你不知道哪些文件实际上已经用UTF-8编码,哪些文件是用windows-1252编码的,那么你必须检查所有文件并自己查找。在最糟糕的情况下,这可能意味着您必须使用两种编码中的任何一种打开它们中的每一种,并查看它们是否“看起来”正确 - 即,所有字符都正确显示。当然,您可以使用工具支持来执行此操作,例如,如果您确定某些字符包含在windows-1252与UTF-8中具有不同映射的文件中,您可以为它们进行grep通过Seva Akekseyev提到的'iconv'运行文件后。
如果您知道文件实际上只包含在UTF-8和Windows-1252中编码相同的字符,那么您的另一个幸运案例就是。在那种情况下,当然,你已经完成了。
答案 4 :(得分:6)
如果你想在一个命令中重命名多个文件 - 让我们说你要转换所有*.txt
文件 - 这是命令:
find . -name "*.txt" -exec iconv -f WINDOWS-1252 -t UTF-8 {} -o {}.ren \; -a -exec mv {}.ren {} \;
答案 5 :(得分:2)
使用 iconv 命令。
要确保文件位于Windows-1252中,请在记事本中打开它(在Windows下),然后单击“另存为”。记事本建议当前编码为默认值;如果它是Windows-1252(或任何1字节代码页,就此而言),它会说“ANSI”。
答案 6 :(得分:1)
您可以使用记事本++等编辑器更改文件的编码。只需转到编码并选择您想要的内容。
我总是喜欢Windows 1252
答案 7 :(得分:0)
如果您确定您的文件是UTF-8或Windows 1252(或Latin1),则可以利用以下事实:如果您尝试转换无效文件,则重新编码将退出并显示错误。
虽然utf8是有效的Win-1252,但反之则不然:win-1252无效UTF-8。所以:
recode utf8..utf16 <unknown.txt >/dev/null || recode cp1252..utf8 <unknown.txt >utf8-2.txt
将为所有cp1252文件吐出错误,然后继续将它们转换为UTF8。
我会把它包装成一个更干净的bash脚本,保留每个转换文件的备份。
在进行字符集转换之前,您可能希望首先确保所有文件中的行结尾一致。否则,重新编码会因此而抱怨,并且可能会转换已经是UTF8的文件,但只是有错误的行尾。
答案 8 :(得分:0)
找到此documentation for the TYPE command:
将ASCII(Windows1252)文件转换为Unicode(UCS-2文件)文本文件:
For /f "tokens=2 delims=:" %%G in ('CHCP') do Set _codepage=%%G
CHCP 1252 >NUL
CMD.EXE /D /A /C (SET/P=ÿþ)<NUL > unicode.txt 2>NUL
CMD.EXE /D /U /C TYPE ascii_file.txt >> unicode.txt
CHCP %_codepage%
上述技术(基于Carlos M.的脚本)首先创建带有字节顺序标记(BOM)的文件,然后附加原始文件的内容。 CHCP用于确保会话与Windows1252代码页一起运行,以便正确解释字符0xFF和0xFE(ÿþ)。
答案 9 :(得分:0)
UTF-8没有BOM,因为它既多余又无效。 BOM有用的地方是UTF-16,可以像Microsoft一样进行字节交换。 UTF-16如果用于内存缓冲区中的内部表示。使用UTF-8进行交换。默认情况下,UTF-8,从US-ASCII和UTF-16派生的任何其他内容都是自然/网络字节顺序。 Microsoft UTF-16需要BOM,因为它是字节交换的。
要将Windows-1252转换为ISO8859-15,我首先将ISO8859-1转换为US-ASCII,以获得具有相似字形的代码。然后我将Windows-1252转换为ISO8859-15,将其他非ISO8859-15字形转换为多个US-ASCII字符。