如何验证变量是否包含 Windows 批处理中的有效文件名



我要求用户使用以下命令在Windows Batch中提供文件名:

set /p my_filename=Enter filename for this project

如何验证%my_filename%是否包含有效的 Windows 文件名(不是路径(,如果不包含,请重新询问用户?

编辑运行脚本时有问题的文件尚不存在(它将由脚本创建(

@echo off
setlocal enableextensions disabledelayedexpansion
:askFile
rem Retrieve filename. On empty input ask again
set /p "my_file=Enter filename for this project: " || goto :askFile
rem Use delayed expansion to avoid problems with special characters
setlocal enabledelayedexpansion
rem Disable delimiters and end of line characters in for command
for /f delims^=^ eol^= %%a in ("!my_file!") do (
rem Cancel delayed expansion to avoid ! removal during expansion
endlocal
rem Until checked, we don't have a valid file
set "my_file="
rem Check we don't have a path, it is not a folder and the file exists
if /i "%%~a"=="%%~nxa" if not exist "%%~a" if exist "%%~a" set "my_file=%%~nxa"
)
rem If we don't have a file name (it was not valid) ask again
if not defined my_file goto :askFile
echo Selected file is "%my_file%"

编辑以适应评论

@echo off
setlocal enableextensions disabledelayedexpansion
:askFile
rem Retrieve filename. On empty input ask again
set /p "my_file=Enter filename for this project: " || goto :askFile
rem See Naming Files, Paths, and Namespaces
rem     https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
rem NOTE: From here, we will be enabling/disabling delayed expansion 
rem       to avoid problems with special characters
setlocal enabledelayedexpansion
rem Ensure we do not have restricted characters in file name trying to use them as 
rem delimiters and requesting the second token in the line
for /f tokens^=2^ delims^=^<^>^:^"^/^^|^?^*^ eol^= %%y in ("[!my_file!]") do (
rem If we are here there is a second token, so, there is a special character
echo Error : Non allowed characters in file name
endlocal & goto :askFile
)
rem Check MAX_PATH (260) limitation
set "my_temp_file=!cd!!my_file!" & if not "!my_temp_file:~260!"=="" (
echo Error : file name too long
endlocal & goto :askFile
)
rem Check path inclusion, file name correction
for /f delims^=^ eol^= %%a in ("!my_file!") do (
rem Cancel delayed expansion to avoid ! removal during expansion
endlocal
rem Until checked, we don't have a valid file
set "my_file="
rem Check we don't have a path 
if /i not "%%~a"=="%%~nxa" (
echo Error : Paths are not allowed
goto :askFile
)
rem Check it is not a folder 
if exist "%%~nxa" (
echo Error : Folder with same name present 
goto :askFile
)
rem ASCII 0-31 check. Check file name can be created
2>nul ( >>"%%~nxa" type nul ) || (
echo Error : File name is not valid for this file system
goto :askFile
)
rem Ensure it was not a special file name by trying to delete the newly created file
2>nul ( del /q /f /a "%%~nxa" ) || (
echo Error : Reserved file name used
goto :askFile
)
rem Everything was OK - We have a file name 
set "my_file=%%~nxa"
)
echo Selected file is "%my_file%"
goto :eof
  • 你可以用一个 for 剥离可能的路径
  • 使用 findstr 正则表达式检查仅允许的字符
  • 另一个用于排除可能的设备名称的查找线程

:: Q:Test2017820SO_45780452.cmd
@Echo off
:loop
set "my_filename="
set /p "my_filename=Enter filename for this project: "
set "test="
for %%A in ("%my_filename%") Do  Set "test=%%~nxA"
If "%test%" neq "%my_filename%" (
Echo no drive/path please
Goto :loop
)
echo:%my_filename%|findstr /i "^[0-9A-Z.-_]*$" >Nul 2>&1 ||(
Echo invalid chars
goto :loop
)
:: check possible device name and reject
echo:%my_filename%|findstr /i "^aux$ ^con$ ^com[0-9]*$ ^lpt[0-9]*$ ^nul$ ^prn$" >Nul 2>&1 && (
Echo invalid device name
goto :loop
)
:: my_filename should be a tolerable name

非常基本的文件名有效性控制:

echo %my_filename%| findstr /R /C:"*.*"

保留的DOS时间名称(CON,PRN,NUL等(和/或某些特殊字符可能会出现故障,因此也许您可以简单地尝试以提供的名称将某些内容存储到文件中,然后检查文件是否成功创建。像这样:

:getfilename
set /p my_filename=Enter filename for this project
echo A>%my_filename%
if not exist %my_filename% (echo Wrong filename & goto getfilename) else (del %my_filename% >NUL)

全部未经测试!!首先检查工作目录是否为空。

最新更新