Pergunta

Existe alguma maneira de descobrir se um arquivo é um diretório?

Eu tenho o nome do arquivo em uma variável. Em Perl eu posso fazer isso:

if(-d $var) { print "it's a directory\n" }
Foi útil?

Solução

Você pode fazê-lo assim:

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

No entanto, isso só funciona para diretórios sem espaços em seus nomes. Quando você adicionar aspas ao redor da variável para lidar com os espaços que irá parar de funcionar. Para lidar com diretórios com espaços, converter o arquivo para o formato curto 8.3 da seguinte forma:

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

Os convertidos %%~si %%i a um nome de ficheiro 8.3. Para ver todos os outros truques que você pode realizar com variáveis ??FOR entrar HELP FOR em um prompt de comando.

(Nota -.. O exemplo dado acima é no formato de trabalhar em um arquivo de lote Para obtê-lo trabalhar na linha de comando, substitua o %% com % em ambos os lugares)

Outras dicas

Isso funciona:

if exist %1\* echo Directory

Obras com nomes de diretório que contém espaços:

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

Note que as aspas são necessárias se o diretório contém espaços:

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

Também pode ser expressa como:

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

Isto é seguro para tentar em casa, as crianças!

Recentemente falhou com abordagens diferentes a partir do acima. A certeza de que funcionou no passado, talvez relacionado com dfs aqui. Agora, usando os arquivos atributos e corte primeiro caractere

@echo off
SETLOCAL ENABLEEXTENSIONS
set ATTR=%~a1
set DIRATTR=%ATTR:~0,1%
if /I "%DIRATTR%"=="d" echo %1 is a folder
:EOF

Na sequência da minha oferta anterior, acho que isso também funciona:

if exist %1\ echo Directory

Não há aspas em torno% 1 são necessários porque o chamador irá fornecê-los. Isso economiza uma tecla toda sobre a minha resposta de há um ano; -)

Aqui está um script que usos para construir um caminho totalmente qualificado, em seguida, pushd para testar se o caminho é um diretório. Observe como ele funciona para caminhos com espaços, bem como os caminhos de rede.

@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

Exemplo de saída com a salvo acima como "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

Isso funciona perfeitamente

if exist "%~1\" echo Directory

precisamos usar% ~ 1 para remover citações de% 1, e adicionar uma barra invertida no final. Em seguida, coloque thw inteiro em qutes novamente.

A técnica NUL parece funcionar apenas em nomes de arquivo 8.3 compatíveis.

(Em outras palavras, `D: \ Documents and Settings` é "ruim" e` D: \ DOCUME ~ 1` é "bom")


Eu acho que há alguma dificuldade em utilizar o tecnique "NUL" quando há espaços no nome do diretório, como "Documents and Settings".

Estou usando o Windows XP Service Pack 2 e lançar o prompt cmd de% SystemRoot% \ system32 \ cmd.exe

Aqui estão alguns exemplos do que não funcionou eo que funciona para mim:

(Estas são todas as manifestações feito "ao vivo" em um. Figura I prompt interativo que você deve fazer as coisas para trabalhar lá antes de tentar depurá-los em um script.)

Isto não funcionou:

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

Isto não funcionou:

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

Este trabalho faz (para mim):

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

[[Olhe aqui !!!! ]]
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

Isso funciona, mas é uma espécie de bobo, porque o ponto já implica estou em um diretório:

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

Isso funciona e também lida com caminhos com espaços entre eles:

dir "%DIR%" > NUL 2>&1

if not errorlevel 1 (
    echo Directory exists.
) else (
    echo Directory does not exist.
)

Provavelmente não é o mais eficiente, mas mais fácil de ler do que as outras soluções em minha opinião.

Uma variação de @ batchman61 abordagem (verificando o atributo Directory).

Desta vez eu usar um comando externo 'achado'.

(Oh, e observe o truque &&. Isso é para evitar a longa sintaxe chato IF ERRORLEVEL.)

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

Saídas sim em:

  • Directories.
  • Diretório links simbólicos ou junções.
  • quebrado do diretório links simbólicos ou junções. (Não tenta ligações resolver.)
  • Directories quais você não tem permissão de leitura na (por exemplo, "C: \ System Volume Information")

Eu uso este:

if not [%1] == [] (
  pushd %~dpn1 2> nul
  if errorlevel == 1 pushd %~dp1
)

Uma maneira muito simples é verificar se existe a criança.

Se uma criança não tem qualquer criança, o comando exist retornará false.

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

Você pode ter algum falso negativo se você não tem direito de acesso suficiente (eu não testei).

Com base este artigo intitulado "Como pode uma existência teste de arquivo de lote de um diretório" é "não inteiramente confiável".

Mas eu só testei isso:

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

e parece trabalho

Aqui está a minha solução:

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

Se você pode cd para ele, é um diretório:

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%

Gostaria de postar meu próprio roteiro função sobre esta esperança sujeito a ser útil para alguém um dia.

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

Este script lote verifica se o arquivo / pasta é existir e se for um arquivo ou uma pasta.

Uso:

script.bat "PATH"

código de saída (s):

0:. Arquivo / pasta não existe

1:. Existe, e é uma pasta

3:. Existe, e é um arquivo

CD retorna um EXIT_FAILURE quando o diretório especificado não existe. E você tem símbolos de processamento condicional , assim que você poderia fazer como o abaixo para isso.

SET cd_backup=%cd%
(CD "%~1" && CD %cd_backup%) || GOTO Error

:Error
CD %cd_backup%

No Windows 7 e XP, eu não posso obtê-lo para contar arquivos vs. dirs em unidades mapeadas. O script a seguir:

@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

produz:

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

Então, cuidado se o seu script pode ser alimentado um caminho mapeado ou UNC. A solução pushd abaixo parece ser o mais infalível.

Este é o código que eu uso nos meus arquivos em lote

```
@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

`` `

Ok ... o truque 'nul' não funciona se você usar aspas em nomes, que representa a maioria dos arquivos com nomes de arquivo longos ou espaços.

Por exemplo,

if exist "C:\nul" echo Directory

não faz nada, mas

if exist C:\nul echo Directory

obras.

Eu finalmente veio com essa, que parecia trabalho para todos os casos:

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

ou se você pode assegurar-lhe atender a todos os requisitos para 'nul' uma solução é:

if exist %~sf1\nul echo Directory

Coloque-as em um arquivo de lote como 'test.bat' e fazer 'test.bat MyFile'.

Aqui está a minha solução depois de muitos testes com se existir, pushd, dir / AD, etc ...

@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
  • Ele funciona com arquivos que não têm extensão
  • Ele funciona com pastas com o nome folder.ext
  • Ele funciona com caminho UNC
  • Ele funciona com entre aspas caminho completo ou com apenas o dirname ou nome de arquivo somente.
  • Ele funciona mesmo se você não tem permissões de leitura
  • Funciona com Diretório Links (junções).
  • Ele funciona com arquivos cujo caminho contém um Link Directory.

Um problema com o uso método %%~si\NUL é que há a chance de que ele adivinha errado. Sua possível ter um nome de arquivo encurtar para o arquivo errado. Eu não acho que %%~si resolve o nome do arquivo 8.3, mas adivinha-lo, mas usando a manipulação de cadeia para encurtar o caminho de arquivo. Eu acredito que se você tem caminhos de arquivo semelhantes ele pode não funcionar.

Um método alternativo:

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

Você pode substituir (goto IsFile)||(goto IsDir) com outros comandos de lote:
(echo Is a File)||(echo is a Directory)

que não podemos simplesmente teste com este:

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

Parece que funciona para mim.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top