命令SET和IF可用于检查分配给环境变量的字符串是否包含特定字符或字符串。
例如:
@echo off
setlocal EnableExtensions
for %%I in ("C:\Users\MikeW" "Folder\FileName" "Folder or file name") do call :ColonBackslash %%I
endlocal
goto :EOF
:ColonBackslash
set "Argument=%~1"
rem Substitute in argument string all colons by nothing and compare this
rem string with unmodified argument string. The argument string contains
rem a colon if the modified and the unmodified strings are not equal.
if not "%Argument::=%" == "%Argument%" (
echo Colon in argument: %Argument%
goto :EOF
)
rem Substitute in argument string all backslashes by nothing and compare
rem this string with unmodified argument string. The argument string
rem contains a backslash if the modified and the unmodified strings
rem are not equal.
if not "%Argument:\=%" == "%Argument%" (
echo Backslash in argument: %Argument%
goto :EOF
)
echo No colon or backslash in: %Argument%
goto :EOF
这个批处理文件输出:
Colon in argument: C:\Users\MikeW
Backslash in argument: Folder\FileName
No colon or backslash in: Folder or file name
比较带有替换字符/字符串的字符串与未修改的字符串可以用来确定输入字符串的类型,如下面的批处理代码所示:
@echo off
setlocal EnableExtensions
for %%I in ("C:\Users\MikeW" "C:\Users\Mi:keW" "documentation" "\\server\share\folder" "\\server\share\folder1\..\folder2" "\\server\share\fo:lder" "\\server\" "\\server\share\folder\..\" "%SystemRoot%\..\" ".\Folder" "..\..\Folder" "\Windows" ">:Invalid") do call :classifyInput %%I
endlocal
goto :EOF
:classifyInput
rem Subroutine called with no parameter or with just "" as parameter.
if "%~1" == "" goto :EOF
set "Argument=%~1"
rem Replace all forward slashes by backslashes in argument string.
set "Argument=%Argument:/=\%"
rem Is the second character a colon and third character a backlash?
if "%Argument:~1,2%" == ":\" goto AbsolutePath
rem Is there a colon anywhere else than at second position in argument?
rem C:Folder is interpreted as invalid argument and not as relative
rem path to subfolder "Folder" of current directory on drive C:.
if not "%Argument::=%" == "%Argument%" (
echo Invalid argument: %1
goto :EOF
)
rem Starts the argument with two backslashes?
if "%Argument:~0,2%" == "\\" goto PathUNC
rem Starts the argument with \ for a path relative to current drive?
if "%Argument:~0,1%" == "\" (
echo Relative path: %1
goto :EOF
)
rem Starts the argument with .\ for a path relative to current directory?
if "%Argument:~0,2%" == ".\" (
echo Relative path: %1
goto :EOF
)
rem Starts the argument with ..\ for a path relative to parent directory?
if "%Argument:~0,3%" == "..\" (
echo Relative path: %1
goto :EOF
)
rem Contains the argument a backslash for a path relative to current directory?
if not "%Argument:\=%" == "%Argument%" (
echo Relative path: %1
goto :EOF
)
echo Name without path: %1
goto :EOF
:AbsolutePath
set "Remaining=%Argument:~2%"
rem Is there a colon anywhere else after second position in argument?
if not "%Remaining::=%" == "%Remaining%" (
echo Invalid argument: %1
goto :EOF
)
rem Is the first character a drive letter if second character is a colon?
set "FirstIsLetter="
for /F "delims=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" %%# in ("%Argument:~0,1%") do set "FirstIsLetter=%%#"
if not "%FirstIsLetter%" == "" (
echo Invalid argument: %1
goto :EOF
)
rem Contains the absolute path also .\ or ..\ in path?
if "%Argument:.\=%" == "%Argument%" (
echo Absolute path: %1
) else (
echo Abs. + rel. path: %1
)
goto :EOF
:PathUNC
rem Does the UNC path contain also a colon?
if not "%Argument::=%" == "%Argument%" (
echo Invalid argument: %1
goto :EOF
)
set "ServerName="
set "ShareName="
set "Remaining="
for /F "tokens=1,2* delims=\" %%A in ("%Argument%") do (
set "ServerName=%%A"
set "ShareName=%%B
set "Remaining=%%C"
)
rem Is there no share name specified after server name in UNC path?
if "%ShareName%" == "" (
echo Invalid argument: %1
goto :EOF
)
rem Is there an invalid share name specified after server name in UNC path?
if "%ShareName%" == "." (
echo Invalid argument: %1
goto :EOF
)
rem Is there an invalid share name specified after server name in UNC path?
if "%ShareName%" == ".." (
echo Invalid argument: %1
goto :EOF
)
rem Contains the UNC path also .\ or ..\ in remaining path?
if "%Remaining:.\=%" == "%Remaining%" (
echo UNC path: %1
) else (
echo UNC + rel. path: %1
)
goto :EOF
输出结果为:
Absolute path: "C:\Users\MikeW"
Invalid argument: "C:\Users\Mi:keW"
Name without path: "documentation"
UNC path: "\\server\share\folder"
UNC + rel. path: "\\server\share\folder1\..\folder2"
Invalid argument: "\\server\share\fo:lder"
Invalid argument: "\\server\"
UNC + rel. path: "\\server\share\folder\..\"
Abs. + rel. path: "C:\WINDOWS\..\"
Relative path: ".\Folder"
Relative path: "..\..\Folder"
Relative path: "\Windows"
Invalid argument: ">:Invalid"
但是,这个批处理代码不完整,无法检查参数字符串中的无效路径、文件夹或文件名。仍然存在很多可能由该批处理代码未检测到的错误。
为了理解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并非常认真地阅读每个命令显示的所有帮助页面。
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
rem /?
set /?
setlocal /?
最好让Windows内核检查参数是否指定了现有文件夹或文件,而不管参数字符串是否带有任何类型的路径并且是否有效。请参阅以下主题:
如果要测试不存在的文件夹/文件的有效性,只需创建文件夹/文件,使用2>nul
抑制错误消息(请参阅Microsoft文章使用命令重定向运算符),并使用if errorlevel 1
或if exist“%~1”
检查文件夹/文件是否可以成功创建,或者此操作失败是因为无效的文件夹/文件名字符串、拒绝访问、缺少权限等原因。
RELATIVE_PATHNAME
。这是有意的,因为我还没来得及处理,我正在努力弄清楚到目前为止出了什么问题。 - Mike Warren:
-- 比如说C:folder
... - aschipflC:folder
是一个相对路径,指定了驱动器C:
上当前目录中的子文件夹folder
。但可以假设C:folder
大约有99.999999999% 的可能是一个错误输入的绝对路径,而不是故意使用的相对路径。在使用 Windows 计算机超过20年的时间里,我从未见过有人故意使用这样的路径作为相对路径。然而,我已经修改了我的答案中的代码,以检查绝对路径。 - MofiD:file.ext
,特别是在有多个磁盘驱动器的情况下。这种“遗留问题”仍然存在于Windows的cmd
中。不管怎样,我只是想指出,在处理路径时,如果使用字符串操作函数而不是与路径相关的函数,可能会出现特殊情况被错误地处理的情况... - aschipfl