我有一个略多于 10,000 个 mp3 文件的播放列表。音乐库共有约 40,000 首曲目。我决定编写一个批处理文件,仅将播放列表上的文件复制到不同驱动器上的目录中。我使用 Notepad++ 修改文本播放列表文件,以便获得正确的路径/文件名。我只需要在路径/文件名周围添加引号,在行中添加“copy”前缀,并在行中添加目标驱动器/目录后缀。完成所有这些,确保批处理文件保存为 UTF-8 并执行它。
几分钟后,批处理文件完成。当我检查目标文件时,我注意到大约 70 个文件尚未复制。我在原始播放列表文件上使用了“Beyond Compare”来与我从复制的文件制作的播放列表文件进行比较。我注意到,未复制的文件的文件名中包含我所说的“欧洲”字符。就像“Dov'é L'Amore.mp3”和“José Feliciano - Feliciano! - 01 - 加州梦.mp3。”其他带有感叹号的文件也没有复制。
我重新运行该文件,用“xcopy”代替“copy”——结果相同。到 Robocopy - 相同的结果。此时,我决定尝试在命令提示符下使用 Robocopy 复制问题文件之一,以查看它报告的错误。惊喜,惊喜——它复制了,其他的也复制了。所以 Robocopy 在命令级别会复制文件,但不会复制到保存为 UTF-8 的批处理文件中??
作为最后的手段,我决定尝试使用 Powershell。但由于我没有使用它的经验,所以我要求 ChatGPT 为我写一个脚本,这就是它返回的内容。
# Source and destination paths
$sourcePath = "F:\Directory\Music\Cher - Bob’s Cher Mix"
$destinationPath = "X:\BoboFMDrive"
# File name with special characters
$fileName = "Cher - My Cher Mix - 02 - Dov' é L'Amore.mp3"
# Full path of the source file
$sourceFile = Join-Path -Path $sourcePath -ChildPath $fileName
# Full path of the destination file
$destinationFile = Join-Path -Path $destinationPath -ChildPath $fileName
# Copy the file to the destination
Copy-Item -Path $sourceFile -Destination $destinationFile -Force
Write-Host "File copied successfully!"
它起作用了!,但我正在寻找一种解决方案,让我可以轻松地编辑包含许多行/字符串的基于文本的文件,因为必须为每个文件创建一个脚本是很繁重的。 有人对解决方案有任何想法吗?我最终只是使用“Beyond Compare”并手动复制删除的文件,但希望为未来找到更好/更简单的解决方案。
问题出在代码页上。默认情况下,Windows 不使用 UTF-8。它使用本地 ANSI 代码页。
UTF-8
的代码页是 65001
使用不同的代码页创建一些文件:
D:\Test> chcp
Active Codepage: 850.
D:\Test> echo . >"Dov' é L'Amore_ansi.mp3"
D:\Test> chcp 65001
Active Codepage: 65001
D:\Test> echo . >"Dov' é L'Amore_utf8.mp3"
D:\Test> chcp 850
Active Codepage: 850.
D:\Test> dir
11.08.2023 17:08 <DIR> .
11.08.2023 17:08 <DIR> ..
11.08.2023 16:56 4 Dov' é L'Amore_ansi.mp3
11.08.2023 16:58 4 Dov' é L'Amore_utf8.mp3
D:\Test> chcp 65001
Active Codepage: 65001
D:\Test> dir
11.08.2023 17:08 <DIR> .
11.08.2023 17:08 <DIR> ..
11.08.2023 16:56 4 Dov' é L'Amore_ansi.mp3
11.08.2023 16:58 4 Dov' é L'Amore_utf8.mp3
D:\Test>
如您所见,没有区别。显然,Windows 内部会在将文件名写入文件系统之前转换所使用的字符集。
=> 因此,在使用命令行和批处理时,您没有任何问题,无需对文件内容进行任何评估。
使用 Windows 的
Notepad.exe
,您可以在操作过程中选择文件编码 Save as ...
。
创建三个文件,其中包含文本
Dov' Ú L'Amore
:
将它们编码保存为
D:\Test> chcp 850
Active Codepage: 850.
D:\Test> type ansi.txt
Dov' Ú L'Amore
D:\Test> type utf8.txt
Dov' ├® L'Amore
D:\Test> type utf8_boom.txt
´╗┐Dov' ├® L'Amore
D:\Test>
D:\Test> chcp 65001
Aktive Codepage: 65001.
D:\Test> type ansi.txt
Dov' � L'Amore
D:\Test> type utf8.txt
Dov' é L'Amore
D:\Test> type utf8_boom.txt
Dov' é L'Amore
D:\Test>
(注意
utf8_boom.txt
内容文字前的空格)
与文件内的文件系统相比,编码与代码页相关。
如果不同步,处理后的文件名将与文件系统中找到的文件名不同。
结果: