如何将文件名从Unicode转换为ASCII

4
我有一堆音乐文件存储在一个挂载在Linux上的NTFS分区中,这些文件名包含Unicode字符。我正在尝试编写一个脚本来重命名这些文件,以便所有文件名只使用ASCII字符。我认为可以使用iconv命令来实现,但我无法为'mv'命令转义字符。
编辑:如果没有直接的Unicode字符翻译也没关系。我想用“?”字符替换它们。

语言?如果这是bash,请将其放在引号中。如果这是其他语言,请不要调用mv,而是调用适当的系统调用。 - Thanatos
另外,如果我们发现一个Unicode字符,我们该怎么办?火没有ASCII等价物。 - Thanatos
3个回答

3

convmv是一个很好的Perl脚本,用于转换文件名编码。但它无法处理目标编码中没有的字符。

您可以使用与Perl一起分发的重命名实用程序,将任何不在ASCII中的字符更改为“?”:

rename 's/[^ -~]/?/g' *

很不幸,这会将多字节字符替换为多个“?”。根据所使用的Unicode编码和涉及的字符,更改正则表达式可能有帮助,例如:

rename 's/[^ -~]{2}/?/g' *

针对双字节字符。


这很棒。只是需要注意一下,现在有些发行版将perl的rename实用程序重打包为“prename”,因为与另一个名为“rename”的二进制文件存在命名冲突。 - BoeroBoy

3
有时,mv在shell中无法读取文件名,所以您可以尝试使用inode引用。

获取文件的inode:

$ ls -il

输出将类似于以下内容:

13377799 -rw-r--r--  1 draco  draco      11809 Apr 25 01:39 some_filename.ext
9340462  -rw-r--r--  1 draco  draco      81648 Apr 23 02:27 some_strange_filename.ext
9340480  -rw-r--r--  1 draco  draco       4717 Apr 23 03:54 yikes__oh_look_a_file_火

然后使用find命令获取你的文件,并可能使用Thanatos提供的Python代码:

$ find . -inum 9340480 -exec ./unistrip.py {} \;

你也可以在shell中使用上述命令和iconv

希望这能帮助到某些人,如果有任何错误,请原谅[第一个答案]。


2

我认为iconv没有任何字符替换功能。在Python中,可以使用以下代码:

#!/usr/bin/python
import sys

def unistrip(s):
    if isinstance(s, str):
        s = s.decode('utf-8')
    chars = []
    for i in s:
        if ord(i) > 0x7f:
            chars.append(u'?')
        else:
            chars.append(i)
    return u''.join(chars)

if __name__ == '__main__':
    print unistrip(sys.argv[1])

然后调用:

$ ./unistrip.py "yikes__oh_look_a_file_火"
yikes_?_oh_look_a_file_?

此外:
$ mv "yikes__oh_look_a_file_火" "`./unistrip.py "yikes__oh_look_a_file_火"`"

在进行大规模移动操作之前,您可以先进行一些测试。建议生成一个mv命令列表(即编写代码以编写脚本),因为您可以在执行移动命令之前查看这些命令。


请纠正我,但我认为iconv确实具有字符替换功能:https://dev59.com/AnI-5IYBdhLWcg3wMFW0 - B Johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接