【问题标题】:Check if an absolute path of a directory or a file name are valid检查目录的绝对路径或文件名是否有效
【发布时间】:2016-07-03 10:50:50
【问题描述】:

我正在创建一个 bat 脚本,我应该检查一个变量是否包含有效的目录绝对路径,以及另一个变量是否包含适用于 Windows 8 及更高版本的文件的有效名称。

那么,我将如何进行这些检查?

谢谢

再见

【问题讨论】:

    标签: validation batch-file filenames absolute-path


    【解决方案1】:

    这比大多数人意识到的要复杂得多。 SO和其他地方有很多关于这个主题的错误信息。有许多“解决方案”看似有效,但在某些情况下却失败了。

    问题可以分为两部分:

    1) 绝对或相对

    您不能简单地将路径转换为使用 FOR 变量“%%~fF”或参数“%~f1”的完整路径并测试它是否与原始字符串匹配(忽略大小写),因为有无限数量的可以编写绝对路径的方式。一个有效的绝对路径可以包含任意数量的\..\\.\。此外,绝对路径可能使用驱动器号,也可能是 UNC 路径。此外,绝对路径中可能包含任意数量的"

    我通过首先删除所有引号来测试路径是绝对路径还是相对路径,然后我使用 FINDSTR 来测试它是否以以下任一开头:

    • 驱动器号,后跟冒号,后跟反斜杠
    • 两个反斜杠

    2) 文件或文件夹或不存在

    使用IF EXISTS path 很容易判断路径是否有效。但是区分文件和文件夹比较困难。

    在 DOS 时代,您可以检查 path\NUL 是否存在,如果存在,那么您就知道该路径是一个文件夹。不幸的是,很多人都误以为这在 Windows 下有效 - 在 Windows 下不可靠

    另一个常见的尝试是测试path\ 是否存在,如果存在,则假设它必须是一个文件夹。这通常似乎可行,但如果路径涉及目录符号链接或联结,则它不起作用

    我将使用的分类代码与 https://stackoverflow.com/a/8669636/1012053 几乎相同,只是我将其用于环境变量而不是批处理参数。

    我使用 FOR 变量 ~a 修饰符来查看文件/文件夹属性。如果我找到d,那么它就是一个文件夹。如果我找到没有d 的属性,那么它就是一个文件。否则,如果我找不到属性,则它不存在。

    另一种似乎可以准确判断文件夹是否存在的方法是测试path\*是否存在,但我对这种方法的经验较少。


    所以把它们放在一起,我得到了

    @echo off
    setlocal
    set var=test.bat
    
    setlocal enableDelayedExpansion
    
    :: Determine absolute or relative
    echo(!var:^"=!|findstr /i "^[A-Z]:[\\] ^[\\][\\]" >nul && set "type=absolute" || set "type=relative"
    
    :: Determine file or folder or not exists
    for /f eol^=^ delims^= %%F in ("!var!") do (
      for /f "tokens=1,2 delims=d" %%A in ("-%%~aF") do if "%%B" neq "" (
        echo %%F = %type% folder
      ) else if "%%A" neq "-" (
        echo %%F = %type% file
      ) else (
        echo %%F does not exist
      )
    )
    

    【讨论】:

    • 不错的答案。顺便说一句, echo(!var... 中的括号有什么目的吗?
    • @wolfrevokcats - 我使用ECHO( 而不是ECHO 只是在扩展的结果是一个空字符串(或只有空格)的情况下。但我刚刚意识到它给出了正确的答案。回显没有( 的空白或空字符串将产生ECHO is off.,这将导致确定“相对”。但第二部分将确定“不存在”(正确答案)。最终结果 - 不,没有充分的理由使用 echo(,但也没有什么坏处。
    • 您为反斜杠 [\\] 指定字符类而不是仅使用 `\` 是否有特定的技术原因,或者仅仅是为了便于阅读?
    • @aschipfl - 是的。通常可以使用 \\,但在某些情况下它不起作用。但是[\\] 总是有效的。我总是使用[\\],而不是试图记住什么在哪里起作用。我在What are the undocumented features and limitations of the Windows FINDSTR command?讨论它
    • 啊,是的,我在您的链接答案中发现了“功能”(\\ 和 \"),谢谢!(实际上我的意思是在我的previous comment 中使用 \\ 但一个消失了将它们包含在``...)中,所以[\\] 完全有道理!
    【解决方案2】:

    这是不言自明的代码。 它需要一个包含要检查的路径的参数。

    set "INPUT_PATH=%~1"
    set "FULL_PATH=%~f1"
    set "SHORT_PATH=%~s1"
    if /i "%INPUT_PATH%"=="%FULL_PATH%" echo this is a full path 
    if exist "%INPUT_PATH%" echo this is an existing path
    if exist %SHORT_PATH%\NUL echo this is a directory
    

    【讨论】:

    • 不。如果存在 ..." 或 UNC 路径,您的绝对路径测试可能会失败。 %short_path%\nul 测试很有趣,但如果为卷禁用了短 8.3 路径,则会失败。见my answer
    猜你喜欢
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 2012-11-30
    • 2011-09-06
    • 2015-06-20
    相关资源
    最近更新 更多