Batch file 如何在Windows命令行或批处理文件中搜索字符串中的斜杠或冒号?
我正在尝试编写一个函数,该函数接受一个参数并将其分类为文件夹名(Batch file 如何在Windows命令行或批处理文件中搜索字符串中的斜杠或冒号?,batch-file,cmd,Batch File,Cmd,我正在尝试编写一个函数,该函数接受一个参数并将其分类为文件夹名(文件夹)、相对路径名、或绝对路径名 到目前为止,我得到的是: @echo off call :classifyInput C:\Users\MikeW echo C:\Users\MikeW is of type %_inputType% call :classifyInput documentation echo documentation is of type %_inputType% goto :EOF :classifyI
文件夹
)、相对路径名
、或绝对路径名
到目前为止,我得到的是:
@echo off
call :classifyInput C:\Users\MikeW
echo C:\Users\MikeW is of type %_inputType%
call :classifyInput documentation
echo documentation is of type %_inputType%
goto :EOF
:classifyInput
SETLOCAL
set _inputType=
rem // a string is a "name of folder" iff it has no '/', '\\' or ':' in it, and a pathname otherwise
echo %1%|findstr /i [\/:] >nul
if %errorlevel% == 1 set _inputType=FOLDER
echo %errorlevel%
rem // a string is a "relative pathname" iff it has no ':' as its second character, and an absolute pathname otherwise
if _inputType == [] & "%1:~2,1% == :" (
_inputType=ABSOLUTE_PATHNAME
echo You gave me absolute pathname.
)
ENDLOCAL & set _inputType=%_inputType%
到目前为止,我的函数在这两种情况下的表现是相同的
此外,Google搜索如何查找字符
/
,\
,:
没有返回任何有用的结果。要回答您的问题,用/
,\
,:
和findstr
查找字符,您可以使用如下正则表达式:
findstr "[\\/:]"
:classifyInput
SETLOCAL
set _inputType=
set input=%~1
rem // a string is a "name of folder" iff it has no '/', '\\' or ':' in it, and a pathname otherwise
echo %input%|findstr /r "\\\\ / :" >nul
if %errorlevel% == 1 (
set _inputType=FOLDER
) else (
if "%input:~1,1%" == ":" (
set _inputType=ABSOLUTE_PATHNAME
echo You gave me absolute pathname.
) else (
set _inputType=RELATIVE_PATHNAME
)
)
ENDLOCAL & set _inputType=%_inputType%
编辑:或者,如果您想在脚本注释中描述的字符串中查找\\
、/
或:
,您可以使用:
findstr /r "\\\\ / :"
由于\
是正则表达式中的转义字符,因此需要将其自身转义,以获得真正的\
。
将其正则表达式中的空白用作或运算符
在继续之前,我想指出代码中的一些小错误并帮助您改进:
- 比较
\u inputType=[]
将比较文字字符串“\u inputType”和字符串“[]”。如果要检查变量是否为空,请使用If defined var
,该变量只有在%var%
不为空时才会变为真(对于相反的行为,使用If not
),或者如果“%var%==”
,则使用。但请确保使用相同的分隔符,因为==
运算符将比较每个单个字符:如果abc==“abc”
将不会执行,但是如果“abc”==“abc”
将执行
子字符串提取仅适用于使用set
定义的环境变量。它不适用于参数变量(也不适用于循环变量)。所以%1:~2,1%
不会得到你想要的。它将用其中参数的值替换%1
,并给出类似C:\Users\MikeW:~2,1%
的内容。如果要从参数中提取,则必须使用参数值设置一个变量,并从该变量中提取:
set input=%~1
rem now you can use %input:~2,1%
在您的代码中,我了解到您需要输入的第二个字符:%input:~2,1%
将为您提供第三个字符,而不是第二个字符。如果是子字符串,请将%var:~n,k%
读为第n个字符后的k个字符。因此,您需要的是%输入:~1,1%
我假定您试图在此行上执行和操作:
if _inputType == [] & "%1:~2,1% == :"
不幸的是,和
以及或
运算符不存在于批处理中,因此您必须通过使用连续的if语句(在应用上述修改后)自己“模拟”和
:
最后我得到了这个:
@echo off
call :classifyInput C:\Users\MikeW
echo C:\Users\MikeW is of type %_inputType%
call :classifyInput documentation
echo documentation is of type %_inputType%
call :classifyInput Documents\Folder\inside
echo Documents\Folder\inside is of type %_inputType%
goto :EOF
:classifyInput
SETLOCAL
set _inputType=
set input=%~1
rem // a string is a "name of folder" iff it has no '/', '\\' or ':' in it, and a pathname otherwise
echo %input%|findstr /r "\\\\ / :" >nul
if %errorlevel% == 1 set _inputType=FOLDER
echo %errorlevel%
rem // a string is a "relative pathname" iff it has no ':' as its second character, and an absolute pathname otherwise
if not defined _inputType if "%input:~1,1%" == ":" (
set _inputType=ABSOLUTE_PATHNAME
echo You gave me absolute pathname.
) else (
set _inputType=RELATIVE_PATHNAME
)
ENDLOCAL & set _inputType=%_inputType%
上述脚本将导致以下结果:
0
You gave me absolute pathname.
C:\Users\MikeW is of type ABSOLUTE_PATHNAME
1
documentation is of type FOLDER
0
Documents\Folder\inside is of type RELATIVE_PATHNAME
PS:如果您可以删除echo%errorlevel%
,则可以简化:classifyInput
功能,如下所示:
findstr "[\\/:]"
:classifyInput
SETLOCAL
set _inputType=
set input=%~1
rem // a string is a "name of folder" iff it has no '/', '\\' or ':' in it, and a pathname otherwise
echo %input%|findstr /r "\\\\ / :" >nul
if %errorlevel% == 1 (
set _inputType=FOLDER
) else (
if "%input:~1,1%" == ":" (
set _inputType=ABSOLUTE_PATHNAME
echo You gave me absolute pathname.
) else (
set _inputType=RELATIVE_PATHNAME
)
)
ENDLOCAL & set _inputType=%_inputType%
命令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"
但是,对于检查参数字符串中的无效路径、文件夹或文件名,此批处理代码不完整。此批处理代码仍有许多可能未检测到的错误
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页面
呼叫/?
echo/?
endlocal/?
获取/?
goto/?
如果/?
rem/?
设置/?
setlocal/?
如果参数字符串不包含或包含任何类型的路径且完全有效,则最好让Windows内核检查参数是否指定独立于现有文件夹或文件。请参阅以下主题:
如果要对不存在的文件夹/文件进行有效性测试,只需创建该文件/文件夹,使用2>nul
(请参阅Microsoft文章)抑制错误消息,并使用检查错误级别1是否为,或使用如果存在“%~1”
检查文件夹/文件是否可以成功创建,或者,如果此操作因无效的文件夹/文件名字符串、拒绝访问、缺少权限等而失败。前言:这不回答如何搜索字符串以查找/
,\
,:
;它集中于路径的正确分类
首先,我强烈建议避免使用纯字符串操作函数进行路径分类,因为这很容易出错;改用路径相关功能
然后,您需要澄清在以下情况下例程应该输出什么:
- 输入类似于
名称
:您将其称为文件夹
,但这也可能指向文件而不是文件夹,或者它甚至不存在,因此我们不知道它是文件还是文件夹;我对这些项目进行分类PURENAME
;请注意,这只是一个特定的相对路径李>
- 输入类似于
\name
:这是我分类的相对的
,类似于您(相对路径名
)李>
- 输入类似于
D:\name
:这是我分类的ABSOLUTE
,与您类似(ABSOLUTE\u路径名