查找 NFD 编码的文件名

Luk*_*eLR 6 linux encoding file-management rsync filenames

我已将一个目录从 Mac 同步到 Linux 机器,其中包含带有特殊字符(元音变音)的文件和文件夹。不幸的是,Mac 使用 NFD 编码(感谢 Apple!),rsync 没有将其转换为 NFC 标准文件名编码。rsync列出这些文件,例如传输期间Einversta?\\#210ndniserkla?\\#210rung.pdf应该包含的文件Einverst\xc3\xa4ndniserkl\xc3\xa4rung.pdf。在 Linux 机器上,这会导致重复文件,例如包含两个同名文件的文件夹Einverst\xc3\xa4ndniserkl\xc3\xa4rung.pdf(一个采用 NFD 编码,一个采用 NFC 编码)。

\n\n

如何找到 NFD 编码的所有文件并将其删除?这必须是可能的,例如通过使用find.

\n

use*_*686 7

有两种方法:

  • 按照要求:尝试将文件名转换为 NFD,看看是否得到与输入相同的输出。如果这样做,文件名已经是 NFD。

  • 更有用:尝试将文件名转换为NFC,看看是否得到相同的结果。如果不这样做,文件名可能是 NFD 或 NFKC 或 NFKD 或混合/格式错误的名称,但仍然不完全是 NFC。

要查找并重命名受影响的文件,请使用convmv

convmv -f utf-8 -t utf-8 --nfc ...
Run Code Online (Sandbox Code Playgroud)

对于更容易编写脚本的东西,您可以使用 Perl 的Unicode::Normalize

find -type f | perl -C -MUnicode::Normalize -n -e'print if $_ eq NFD($_)'
Run Code Online (Sandbox Code Playgroud)

要查找所有非 NFC 名称(包括 NFD 和非标准化名称):

find -type f | perl -C -MUnicode::Normalize -n -e'print if $_ ne NFC($_)'
Run Code Online (Sandbox Code Playgroud)