我有许多 zip 文件,其中存在德语变音符号 (äüöÄÜÖß) 的编码错误。这些错误出现在 filename.zip 以及所包含的目录和文件中,如下所示:
- Fünf = Fu╠ênf
- Räuber = Ra╠êuber
- Überfall = U╠êberfall
等等。通常我使用 Linux,但由于这个问题,我也尝试了 Windows7 VM,但结果还是一样编码混乱。在 Linux 上,我尝试了 convmv 和 detox,但没有成功。
当我使用
- convmv -f iso-8859-1 -t utf8 --replace --notest -r *
我收到“跳过,已经是 UTF-8”的提示。
对此有什么想法吗?
答案1
您收到“已为 UTF-8”警告的原因是这些字符串实际上已经是 UTF-8 格式。“ü”字符被编码为 OSX 样式的“u”,后跟两个字节“\xCC”和“\x88”。这两个字节一起构成了 \u0308(组合分音符)的 UTF-8 表示形式。
如果你看一下代码页 437 列表这里,您将看到 \xCC 字符为“╠”,\x88 字符为“ê”。
无论您使用什么来显示这些字符序列,都不会将它们解释为 UTF-8,而是 CP437。
如果你读过 ruby,那么可以快速证明一下,它在我的 UTF-8 终端上显示的内容与预期一致:
$ ruby -e 'puts "u\xCC\x88"' | iconv -f cp437 -t utf-8
ü
$ ruby -e 'puts "u\xCC\x88"'
ü
答案2
警告:草稿!
我尝试使用“detox”来解决这个问题,但找不到将角色串联在一起的方法。根据@S2VpdGgA 的回答,我制作了此概要。
因为我预览了我所做的一切(使用回声),所以在这些罕见的情况下对我来说是安全的。
但实际上有人可能想正确地做到这一点。可能还有很多其他情况,如“é”、“à”、“è”等……
######
# Preparation and tests
# You may need to extract your own character group from your filename, if this gets lost via this web form.
# My reconstruction as follows:
# note: the echo sends the chain of chars, copied from the console.
echo 'ä' | perl -pe 's/([^x\0-\x7f])/"\\x" . sprintf "%x", ord $1/ge'
echo 'ä' | sed -e 's/a\xcc\x88/ä/'
echo 'ö' | perl -pe 's/([^x\0-\x7f])/"\\x" . sprintf "%x", ord $1/ge'
echo 'ö' | sed -e 's/o\xcc\x88/ö/'
echo 'ü' | perl -pe 's/([^x\0-\x7f])/"\\x" . sprintf "%x", ord $1/ge'
echo 'ü' | sed -e 's/u\xcc\x88/ü/'
echo 'Ä' | perl -pe 's/([^x\0-\x7f])/"\\x" . sprintf "%x", ord $1/ge'
echo 'Ä' | sed -e 's/A\xcc\x88/Ä/'
echo 'Ö' | perl -pe 's/([^x\0-\x7f])/"\\x" . sprintf "%x", ord $1/ge'
echo 'Ö' | sed -e 's/O\xcc\x88/Ö/'
echo 'Ü' | perl -pe 's/([^x\0-\x7f])/"\\x" . sprintf "%x", ord $1/ge'
echo 'Ü' | sed -e 's/U\xcc\x88/Ü/'
# Final version
# test all at once
echo 'Ä' | sed -e 's/a\xcc\x88/ä/' | sed -e 's/o\xcc\x88/ö/' | sed -e 's/u\xcc\x88/ü/' | sed -e 's/A\xcc\x88/Ä/' | sed -e 's/O\xcc\x88/Ö/' | sed -e 's/U\xcc\x88/Ü/'
# wrap into a recursion
# note: not recursive as-is because folder can change
cd /path/to/dir
find . -maxdepth 1 | while read FILE ; do
newfile="$(echo ${FILE} | sed -e 's/a\xcc\x88/ä/' | sed -e 's/o\xcc\x88/ö/' | sed -e 's/u\xcc\x88/ü/' | sed -e 's/A\xcc\x88/Ä/' | sed -e 's/O\xcc\x88/Ö/' | sed -e 's/U\xcc\x88/Ü/')" ;
echo mv -T "${FILE}" "${newfile}";
done
# (remove the 'echo ' to actually make changes)
#######
答案3
我猜是你试图解压或操作文件的文件系统。FAT32 不会喜欢你的变音符号。尝试将这些文件从闪存驱动器(或你拥有的任何东西)中复制出来,然后然后解压缩 zip 文件以查看文件名产生什么样的字符。
NTFS(Windows)和Ext4(Mint)的名称编码都不应该有问题。
当您将 zip 文件本身在 FAT32 系统上复制到适当的支持文件系统时,它们的名称编码很可能不会改变或被修复,但解压缩时的子目录应该没问题。
答案4
首先请注意,字符编码本身就是地狱的一部分。在 Windows 世界中,UTF-8 和 M$ 之间仍然存在着令人讨厌的二元论,M$ 长期以来一直装傻,坚持使用 ISO-8859(猜猜是谁想出来的)。如上所述,这几乎肯定与文件系统有关。我的解决方案不是技术性的,而是多年来一直为我所用的解决方案:
我个人对文件名的建议始终如一:只使用字母数字加破折号 ( - ) 和下划线 ( _ )。将变音符号写为 ae、ue 和 oe。不要使用空格和其他特殊字符。一开始这有点不方便,但它会在意想不到的地方为你省去很多麻烦。
附注:是的,这有点像是卑鄙的“黑客行为”,但如果你跨平台工作,你经常不得不回到最后一个共同点。你会理所当然地认为字符编码等基本的东西会是一个硬性标准,但事实证明,标准很难获得。这西科光盘总结得很好