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

时间:2017-08-20 09:14:49

标签: validation batch-file

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

set /p my_filename=Enter filename for this project

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

修改 运行脚本时,该文件尚不存在(它将由脚本创建)

3 个答案:

答案 0 :(得分:2)

  • 您可以使用for
  • 删除posible路径
  • 使用findstr正则表达式检查仅允许的字符
  • 排除可能的设备名称的另一个问题
:: Q:\Test\2017\08\20\SO_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

答案 1 :(得分:2)

@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

答案 2 :(得分:1)

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

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)

所有人都没有!首先检查工作目录是否为空。