如何替换文件名中的特殊字符

how to replace special characters in file names

我们正在迁移到 OneDrive for Business。要将文件存储在 OneDrive 中,文件名中不能包含以下字符: /:*?"<>|#% 此外,不支持以波浪号 (~) 开头的文件名。 我想用破折号搜索并替换特殊字符。 有人有批处理文件或 powershell 脚本吗?

巧合的是,Windows 文件名中也不允许使用 \ / : * ? " < > |,因此您列表中的大部分内容都不是问题。假设字符列表是完整的,剩下的就是散列、百分比和前导波浪号。

@echo off
setlocal

:: replace ~ only if first char of filename
for %%I in ("~*") do (
    set "file=%%~I"
    setlocal enabledelayedexpansion
    echo %%~I -^> -!file:~1!
    ren "%%~I" "-!file:~1!"
    endlocal
)

:: replace # or % everywhere in filename
for %%d in (# %%) do (
    for %%I in ("*%%d*") do (
        set "file=%%~I"
        setlocal enabledelayedexpansion
        echo %%~I -^> !file:%%d=-!
        ren "%%~I" "!file:%%d=-!"
        endlocal
    )
)

但正如 Dour 指出的那样,这只能解决部分问题。您的文件上传 might still require some hand-holding。或者谁知道?这可以解决你所有的世俗问题。 耸肩


编辑: O.P。问及将 /r 添加到 for 循环以使替换递归。您 可以 通过一些调整来做到这一点,但您最终将循环遍历文件列表 3 次 -- 每个要替换的符号一次。我建议这将是一种更有效的方法:

@echo off
setlocal enabledelayedexpansion

if "%~1"=="" goto usage
if not exist "%~1" goto usage
pushd "%~1"

for /r %%I in (*) do (
    set "file=%%~nxI"
    if "!file:~0,1!"=="~" (
        set "file=-!file:~1!"
    )
    for %%d in (# %%) do (
        if not "!file!"=="!file:%%d=!" (
            set "file=!file:%%d=-!"
        )
    )
    if not "!file!"=="%%~nxI" (
        echo %%~fI -^> !file!
        ren "%%~fI" "!file!"
    )
)

goto :EOF

:usage
echo Usage: %~nx0 pathname
echo To operate on the current directory, use a dot as the pathname.
echo Example: %~nx0 .

编辑 2: 添加了参数语法。