我有一个目录,其中包含来自外部来源的大约 10,000 个图像文件。
许多文件名包含空格和标点符号,这些符号对数据库或网络都不太友好。我还想在每个文件名的末尾附加一个 SKU 编号(用于会计目的)。许多(如果不是大多数)文件名还包含扩展拉丁字符我想保留它为了 SEO 目的(具体来说,文件名准确地代表 Google 图片中的文件内容)
我编写了一个 bash 脚本,可以将所有文件重命名(复制)为我想要的结果。bash 脚本以 UTF-8 保存。运行后,它会忽略大约 500 个文件(无法统计文件...)。
我跑了convmv-f UTF-8-t UTF-8在目录中,发现这 500 个文件名是不是采用 UTF-8 编码(convmv 能够检测并忽略已经采用 UTF-8 编码的文件名)
有没有简单的方法可以让我找到哪个他们目前使用的语言编码?
我自己能找到的唯一方法是将终端编码设置为 UTF-8,然后使用 convmv 遍历所有可能的候选编码,直到显示“看起来正确”的转换名称。我无法确定这 500 个文件是否都使用相同的编码,因此我需要重复此过程 500 次。我想要一种比“看起来正确”更自动化的方法!!!
答案1
实际上,没有 100% 准确的方法,但有一种方法可以给出一个很好的猜测。
有一个 Python 库 chardet,可在此处使用:https://pypi.python.org/pypi/chardet
例如
查看当前 LANG 变量的设置:
$ echo $LANG
en_IE.UTF-8
创建需要使用 UTF-8 编码的文件名
$ touch mÉ.txt
更改我们的编码,看看当我们尝试列出它时会发生什么
$ ls m*
mÉ.txt
$ export LANG=C
$ ls m*
m??.txt
好的,现在我们有一个用 UTF-8 编码的文件名,并且我们当前的语言环境是 C(标准 Unix 代码页)。
因此,启动 python,导入 chardet 并让它读取文件名。我使用一些 shell 通配符(即通过 * 通配符扩展)来获取我的文件。将“ls m*”更改为与您的示例文件之一匹配的任何内容。
>>> import chardet
>>> import os
>>> chardet.detect(os.popen("ls m*").read())
{'confidence': 0.505, 'encoding': 'utf-8'}
如您所见,这只是一个猜测。“confidence”变量显示猜测的准确性。
答案2
您可能会发现这很有用,可以测试当前工作目录(python 2.7):
import chardet
import os
for n in os.listdir('.'):
print '%s => %s (%s)' % (n, chardet.detect(n)['encoding'], chardet.detect(n)['confidence'])
结果如下:
Vorlagen => ascii (1.0)
examples.desktop => ascii (1.0)
Öffentlich => ISO-8859-2 (0.755682154041)
Videos => ascii (1.0)
.bash_history => ascii (1.0)
Arbeitsfläche => EUC-KR (0.99)
要从当前目录递归路径,请将其剪切并粘贴到一个小的 Python 脚本中:
#!/usr/bin/python
import chardet
import os
for root, dirs, names in os.walk('.'):
print root
for n in names:
print '%s => %s (%s)' % (n, chardet.detect(n)['encoding'], chardet.detect(n)['confidence'])
答案3
2021 年使用 python3 登陆这里时,我发现 @philip-reynoldsn @klaus-kappel 的答案很有用,但不再起作用,因为chardet.detect()
需要一个字节类对象。我稍微编辑了代码以获取当前工作目录中所有文件的编码,如下所示:
import os
import chardet
for n in os.listdir('.'):
chardet.detect(os.fsencode(n))