代码之家  ›  专栏  ›  技术社区  ›  Vhaerun

如何测试文件是否是批处理脚本中的目录?

  •  63
  • Vhaerun  · 技术社区  · 16 年前

    有没有办法找出一个文件是否是一个目录?

    文件名在变量中。在Perl中,我可以这样做:

    if(-d $var) { print "it's a directory\n" }
    
    22 回复  |  直到 6 年前
        1
  •  46
  •   Kevin Fegan    8 年前

    你可以这样做:

    IF EXIST %VAR%\NUL ECHO It's a directory
    

    但是,这只适用于名称中没有空格的目录。在变量周围添加引号以处理空格时,变量将停止工作。要处理带有空格的目录,请将文件名转换为short 8.3格式,如下所示:

    FOR %%i IN (%VAR%) DO IF EXIST %%~si\NUL ECHO It's a directory
    

    这个 %%~si 皈依者 %%i 到8.3文件名。看看你能表演的其他技巧 FOR 变量输入 HELP FOR 在命令提示下。

    (注意-上面给出的示例采用批处理文件中的工作格式。要使其在命令行上工作,请替换 %% 具有 % 在两个地方。)

        2
  •  78
  •   Dave Jarvis aSterX    8 年前

    这工作:

    if exist %1\* echo Directory
    

    使用包含空格的目录名:

    C:\>if exist "c:\Program Files\*" echo Directory
    Directory
    

    请注意,如果目录包含空格,则需要引号:

    C:\>if exist c:\Program Files\* echo Directory
    

    也可以表示为:

    C:\>SET D="C:\Program Files"
    C:\>if exist %D%\* echo Directory
    Directory
    

    孩子们,在家里试一试是安全的!

        3
  •  43
  •   phuclv    7 年前

    最近失败的方法与上述不同。很肯定他们过去工作过,可能和这里的DFS有关。现在使用 files attributes 切第一个字符

    @echo off
    SETLOCAL ENABLEEXTENSIONS
    set ATTR=%~a1
    set DIRATTR=%ATTR:~0,1%
    if /I "%DIRATTR%"=="d" echo %1 is a folder
    :EOF
    
        4
  •  12
  •   Gerard    14 年前

    在我之前的产品中,我发现这同样有效:

    if exist %1\ echo Directory
    

    %1周围不需要引号,因为调用方将提供它们。 这比我一年前的答案节省了整整一次击键;-)

        5
  •  9
  •   indiv Olivier Poulin    16 年前

    下面是一个脚本,它使用for构建一个完全限定的路径,然后通过pushd测试该路径是否是一个目录。请注意,它是如何处理具有空间的路径以及网络路径的。

    @echo off
    if [%1]==[] goto usage
    
    for /f "delims=" %%i in ("%~1") do set MYPATH="%%~fi"
    pushd %MYPATH% 2>nul
    if errorlevel 1 goto notdir
    goto isdir
    
    :notdir
    echo not a directory
    goto exit
    
    :isdir
    popd
    echo is a directory
    goto exit
    
    :usage
    echo Usage:  %0 DIRECTORY_TO_TEST
    
    :exit
    

    上面保存为“isdir.bat”的样本输出:

    C:\>isdir c:\Windows\system32
    is a directory
    
    C:\>isdir c:\Windows\system32\wow32.dll
    not a directory
    
    C:\>isdir c:\notadir
    not a directory
    
    C:\>isdir "C:\Documents and Settings"
    is a directory
    
    C:\>isdir \
    is a directory
    
    C:\>isdir \\ninja\SharedDocs\cpu-z
    is a directory
    
    C:\>isdir \\ninja\SharedDocs\cpu-z\cpuz.ini
    not a directory
    
        6
  •  6
  •   Aziz    13 年前

    这个很好用

    if exist "%~1\" echo Directory
    

    我们需要使用%~1从%1中删除引号,并在结尾添加反斜杠。然后再把这整个放到量子曲里。

        7
  •  3
  •   pestophagous    16 年前

    nul技术似乎只适用于8.3兼容的文件名。

    (换句话说,`D:\documents and settings`是“坏的”,`D:\docume~1`是“好的”)。


    我认为在目录名中有空格(如“文档和设置”)时,使用“nul”tecnique有些困难。

    我正在使用Windows XP Service Pack 2并从%SystemRoot%\System32\Cmd.exe启动Cmd提示

    以下是一些不起作用和对我起作用的例子:

    (这些都是在交互式提示下“实时”完成的演示。我认为,在尝试在脚本中调试之前,您应该先让它们在那里工作。)

    这不起作用:

    D:\Documents and Settings>if exist "D:\Documents and Settings\NUL" echo yes

    这不起作用:

    D:\Documents and Settings>if exist D:\Documents and Settings\NUL echo yes

    这确实有效(对我而言):

    D:\Documents and Settings>cd ..

    D:\>REM get the short 8.3 name for the file

    D:\>dir /x

    Volume in drive D has no label. Volume Serial Number is 34BE-F9C9

    Directory of D:\
    09/25/2008 05:09 PM <DIR> 2008
    09/25/2008 05:14 PM <DIR> 200809~1.25 2008.09.25
    09/23/2008 03:44 PM <DIR> BOOST_~3 boost_repo_working_copy
    09/02/2008 02:13 PM 486,128 CHROME~1.EXE ChromeSetup.exe
    02/14/2008 12:32 PM <DIR> cygwin

    看这里!!!!!]
    09/25/2008 08:34 AM <DIR> DOCUME~1 Documents and Settings

    09/11/2008 01:57 PM 0 EMPTY_~1.TXT empty_testcopy_file.txt
    01/21/2008 06:58 PM <DIR> NATION~1 National Instruments Downloads
    10/12/2007 11:25 AM <DIR> NVIDIA
    05/13/2008 09:42 AM <DIR> Office10
    09/19/2008 11:08 AM <DIR> PROGRA~1 Program Files
    12/02/1999 02:54 PM 24,576 setx.exe
    09/15/2008 11:19 AM <DIR> TEMP
    02/14/2008 12:26 PM <DIR> tmp
    01/21/2008 07:05 PM <DIR> VXIPNP
    09/23/2008 12:15 PM <DIR> WINDOWS
    02/21/2008 03:49 PM <DIR> wx28
    02/29/2008 01:47 PM <DIR> WXWIDG~2 wxWidgets
    3 File(s) 510,704 bytes
    20 Dir(s) 238,250,901,504 bytes free

    D:\>REM now use the \NUL test with the 8.3 name

    D:\>if exist d:\docume~1\NUL echo yes

    yes

    这是可行的,但有点傻,因为点已经暗示我在一个目录中:

    D:\Documents and Settings>if exist .\NUL echo yes

        8
  •  3
  •   Samuel    9 年前

    这可以工作,也可以处理其中包含空格的路径:

    dir "%DIR%" > NUL 2>&1
    
    if not errorlevel 1 (
        echo Directory exists.
    ) else (
        echo Directory does not exist.
    )
    

    可能不是最有效的,但比我认为的其他解决方案更容易阅读。

        9
  •  3
  •   Explorer09    9 年前

    @batchman61方法的变体(检查directory属性)。

    这次我使用一个外部的“find”命令。

    (哦,注意 && 诡计。这是为了避免长时间的无聊 IF ERRORLEVEL 语法。

    @ECHO OFF
    SETLOCAL EnableExtentions
    ECHO.%~a1 | find "d" >NUL 2>NUL && (
        ECHO %1 is a directory
    )
    

    输出:是的:

    • 目录。
    • 目录符号链接或连接。
    • 破碎的 目录符号链接或连接。(不尝试解析链接。)
    • 您没有读取权限的目录(例如“C:\系统卷信息”)。
        10
  •  2
  •   Kimae    14 年前

    我用这个:

    if not [%1] == [] (
      pushd %~dpn1 2> nul
      if errorlevel == 1 pushd %~dp1
    )
    
        11
  •  2
  •   Eva Dias Abdul Jabbar    12 年前

    一个非常简单的方法是检查孩子是否存在。

    如果孩子没有孩子, exist 命令将返回false。

    IF EXIST %1\. (
      echo %1 is a folder
    ) else (
      echo %1 is a file
    )
    

    如果您没有足够的访问权限(我没有测试过),您可能会有一些错误的否定。

        12
  •  1
  •   Aaron Thoma Sam Brinck    12 年前

    基于 this article 标题为“一个批处理文件如何测试目录的存在性”,它“不完全可靠”。

    但我只是测试了一下:

    @echo off
    IF EXIST %1\NUL goto print
    ECHO not dir
    pause
    exit
    :print
    ECHO It's a directory
    pause
    

    它似乎起作用了

        13
  •  1
  •   user966939    10 年前

    我的解决方案是:

    REM make sure ERRORLEVEL is 0
    TYPE NUL
    
    REM try to PUSHD into the path (store current dir and switch to another one)
    PUSHD "insert path here..." >NUL 2>&1
    
    REM if ERRORLEVEL is still 0, it's most definitely a directory
    IF %ERRORLEVEL% EQU 0 command...
    
    REM if needed/wanted, go back to previous directory
    POPD
    
        14
  •  1
  •   Frank N dqthe    9 年前

    如果你能 cd 它是一个目录:

    set cwd=%cd%
    
    cd /D "%1" 2> nul
    @IF %errorlevel%==0 GOTO end
    
    cd /D "%~dp1"
    @echo This is a file.
    
    @goto end2
    :end
    @echo This is a directory
    :end2
    
    @REM restore prior directory
    @cd %cwd%
    
        15
  •  1
  •   M. Jamal    7 年前

    我想发表我自己关于这个主题的函数脚本,希望有一天对某人有用。

    @pushd %~dp1
    @if not exist "%~nx1" (
            popd
            exit /b 0
    ) else (
            if exist "%~nx1\*" (
                    popd
                    exit /b 1
            ) else (
                    popd
                    exit /b 3
            )
    )
    

    此批处理脚本检查文件/文件夹是否存在以及是文件还是文件夹。

    用途:

    script.bat“路径”

    退出代码(S):

    0:文件/文件夹不存在。

    1:存在,是一个文件夹。

    3:存在,是一个文件。

        16
  •  1
  •   Константин Ван    6 年前

    CD 返回一个 EXIT_FAILURE 当指定的目录不存在时。你得到了 conditional processing symbols ,所以您可以这样做。

    SET cd_backup=%cd%
    (CD "%~1" && CD %cd_backup%) || GOTO Error
    
    :Error
    CD %cd_backup%
    
        17
  •  0
  •   user117529    13 年前

    在Windows7和XP下,我无法让它告诉映射驱动器上的文件和目录。以下脚本:

    @echo off
    if exist c:\temp\data.csv echo data.csv is a file
    if exist c:\temp\data.csv\ echo data.csv is a directory
    if exist c:\temp\data.csv\nul echo data.csv is a directory
    if exist k:\temp\nonexistent.txt echo nonexistent.txt is a file
    if exist k:\temp\something.txt echo something.txt is a file
    if exist k:\temp\something.txt\ echo something.txt is a directory
    if exist k:\temp\something.txt\nul echo something.txt is a directory
    

    生产:

    data.csv is a file
    something.txt is a file
    something.txt is a directory
    something.txt is a directory
    

    因此,如果脚本可能是由映射路径或UNC路径提供的,请小心。下面的强制解决方案似乎是最简单的。

        18
  •  0
  •   gialloporpora    12 年前

    这是我在批处理文件中使用的代码

    ```
    @echo off
    set param=%~1
    set tempfile=__temp__.txt
    dir /b/ad > %tempfile%
    set isfolder=false
    for /f "delims=" %%i in (temp.txt) do if /i  "%%i"=="%param%" set isfolder=true
    del %tempfile%
    echo %isfolder%
    if %isfolder%==true echo %param% is a directory
    

    ` `

        19
  •  0
  •   DrBB    11 年前

    好啊。。。如果在文件名中使用引号,“nul”技巧就不起作用了,因为引号占大多数文件名或空格较长的文件。

    例如,

    if exist "C:\nul" echo Directory
    

    什么都不做,但是

    if exist C:\nul echo Directory
    

    作品。

    我终于想出了这个办法,它似乎适用于所有情况:

    for /f %%i in ('DIR /A:D /B %~dp1 ^| findstr /X /c:"%~nx1"') do echo Directory
    

    或者,如果您可以确保满足“NUL”的所有要求,解决方案是:

    if exist %~sf1\nul echo Directory
    

    把它们放到一个批处理文件中,比如“test.bat”,然后执行“test.bat myfile”。

        20
  •  0
  •   Amr Ali    9 年前

    这是我的解决方案,经过多次测试,如果存在,pushd,dir/ad等…

    @echo off
    cd /d C:\
    for /f "delims=" %%I in ('dir /a /ogn /b') do (
        call :isdir "%%I"
        if errorlevel 1 (echo F: %%~fI) else echo D: %%~fI
    )
    cmd/k
    
    :isdir
    echo.%~a1 | findstr /b "d" >nul
    exit /b %errorlevel%
    
    :: Errorlevel
    :: 0 = folder
    :: 1 = file or item not found
    
    • 它适用于没有扩展名的文件
    • 它与名为folder.ext的文件夹一起使用
    • 它与UNC路径一起工作
    • 它使用双引号的完整路径,或者只使用dirname或文件名。
    • 即使您没有读取权限,它也能工作
    • 它与目录链接(连接)一起工作。
    • 它与路径包含目录链接的文件一起工作。
        21
  •  0
  •   Kevin Fegan    8 年前

    使用中的一个问题 %%~si\NUL 方法是它有可能猜错。文件名可能缩短为错误的文件。我不认为 %%~si 解析8.3文件名,但猜对了,但使用字符串操作来缩短文件路径。我相信如果你有类似的文件路径,它可能不会工作。

    另一种方法:

    dir /AD %F% 2>&1 | findstr /C:"Not Found">NUL:&&(goto IsFile)||(goto IsDir)
    
    :IsFile
      echo %F% is a file
      goto done
    
    :IsDir
      echo %F% is a directory
      goto done
    
    :done
    

    你可以代替 (goto IsFile)||(goto IsDir) 使用其他批处理命令:
    (echo Is a File)||(echo is a Directory)

        22
  •  -2
  •   Lucien Baron    11 年前

    我们不能用这个来测试一下吗?

    IF [%~x1] == [] ECHO Directory
    

    这似乎对我有用。