it-swarm.it

Come verificare se un file è una directory in uno script batch?

C'è un modo per scoprire se un file è una directory?

Ho il nome del file in una variabile. In Perl posso farlo:

if(-d $var) { print "it's a directory\n" }
63
Vhaerun

Puoi farlo in questo modo:

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

Tuttavia, questo funziona solo per le directory senza spazi nei loro nomi. Quando aggiungi le virgolette attorno alla variabile per gestire gli spazi, smetterà di funzionare. Per gestire le directory con spazi, convertire il nome file nel formato breve 8.3 come segue:

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

Il %%~si converte %%i in un nome file 8.3. Per vedere tutti gli altri trucchi che è possibile eseguire con le variabili FOR, immettere HELP FOR al prompt dei comandi.

(Nota: l'esempio sopra riportato è nel formato per lavorare in un file batch. Per farlo funzionare sulla riga di comando, sostituire %% con % in entrambe le posizioni.)

46
Dave Webb

Questo funziona:

if exist %1\* echo Directory

Funziona con nomi di directory che contengono spazi:

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

Si noti che le virgolette sono necessarie se la directory contiene spazi:

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

Può anche essere espresso come:

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

Questo è sicuro da provare a casa, ragazzi!

78
Gerard

Recentemente fallito con approcci diversi da quanto sopra. Abbastanza sicuro che abbiano lavorato in passato, forse in relazione a dfs qui. Ora usando gli attributi files e taglia il primo carattere

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

Oltre alla mia precedente offerta, trovo che anche questo funzioni:

if exist %1\ echo Directory

Non sono necessarie virgolette intorno al% 1 perché il chiamante le fornirà . Ciò consente di salvare un'intera sequenza di tasti rispetto alla mia risposta di un anno fa ;-)

12
Gerard

Ecco uno script che utilizza FOR per creare un percorso completo e quindi pushd per verificare se il percorso è una directory. Osserva come funziona per i percorsi con spazi, così come i percorsi di rete.

@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

Esempio di output con il precedente salvato come "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
9
indiv

Questo funziona perfettamente

if exist "%~1\" echo Directory

dobbiamo usare% ~ 1 per rimuovere le virgolette da% 1 e aggiungere una barra rovesciata alla fine. Poi metti di nuovo tutto in qutes.

6
Aziz

Una variante dell'approccio di @ batchman61 (verificando l'attributo Directory).

Questa volta utilizzo un comando esterno "trova".

(Oh, e nota il trucco &&. Questo per evitare la sintassi lunga IF ERRORLEVEL noiosa.)

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

Uscite sì su:

  • Directory.
  • Directory collegamenti simbolici o giunzioni.
  • Broken directory collegamenti simbolici o giunzioni. (Non tenta di risolvere i collegamenti.)
  • Directory su cui non si dispone dell'autorizzazione di lettura (ad esempio "C:\System Volume Information")
3
Explorer09

Funziona e gestisce anche percorsi con spazi in essi:

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

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

Probabilmente non è la più efficiente ma più facile da leggere rispetto alle altre soluzioni secondo me.

3
Samuel

La tecnica NUL sembra funzionare solo su nomi di file compatibili con 8.3.

(In altre parole, `D:\Documents and Settings` è" cattivo "e` D:\DOCUME ~ 1` è "buono")


Penso che ci sia qualche difficoltà nell'usare la tecnica "NUL" quando ci sono degli SPACES nel nome della directory, come "Documents and Settings."

Utilizzo Windows XP service pack 2 e avvio del prompt cmd da% SystemRoot%\system32\cmd.exe

Ecco alcuni esempi di cosa DID NON funziona e cosa FUNZIONA per me:

(Queste sono tutte le dimostrazioni fatte "dal vivo" a un prompt interattivo. Immagino che dovresti far funzionare le cose lì prima di provare a eseguirne il debug in uno script.)

Questo DID NON funziona:

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

Questo DID NON funziona:

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

Questo funziona (per me):

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

[[Guarda qui !!!! ]]
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

Funziona, ma è un po 'sciocco, perché il punto indica già che sono in una directory:

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

3
pestophagous

Un modo molto semplice è verificare se il bambino esiste.

Se un bambino non ha figli, il comando exist restituirà false.

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

Potresti avere qualche falso negativo se non hai accesso sufficiente a destra (non l'ho testato).

2
Cedric

Io uso questo:

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

Vorrei pubblicare il mio script di funzioni su questo argomento spero di essere utile per qualcuno un giorno.

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

Questo script batch controlla se il file/cartella esiste e se si tratta di un file o di una cartella.

Utilizzo:

script.bat "PATH"

Codice (i) di uscita:

0: file/cartella non esiste.

1: esiste ed è una cartella.

3: esiste ed è un file.

1
M. Jamal

Ecco la mia soluzione:

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
1
user966939

CD restituisce un EXIT_FAILURE quando la directory specificata non esiste. E hai i simboli di elaborazione condizionale , quindi potresti fare come segue per questo.

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

:Error
CD %cd_backup%

Se puoi cd in esso, è una directory:

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%
1
Frank Nocke

Basato su questo articolo intitolato "Come può un file batch testare l'esistenza di una directory" non è del tutto affidabile ".

MA ho appena provato questo:

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

e sembra funzionare

1
Roman M

Ecco la mia soluzione dopo molti test con if exist, pushd, dir/AD, ecc ...

@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
  • Funziona con file senza estensione
  • Funziona con le cartelle denominate folder.ext
  • Funziona con il percorso UNC
  • Funziona con percorso completo con doppia quotatura o solo con la dirname o il nome file.
  • Funziona anche se non hai i permessi di lettura
  • Funziona con i collegamenti di directory (giunzioni).
  • Funziona con file il cui percorso contiene un collegamento di directory.
0
Amr Ali

Un problema con l'utilizzo del metodo %%~si\NUL è che c'è la possibilità che indovina. È possibile avere un nome di file abbreviato nel file sbagliato. Non credo che %%~si risolva il nome file 8.3, ma lo indovina, ma usando la manipolazione delle stringhe per abbreviare il percorso file. Credo che se hai percorsi di file simili potrebbe non funzionare.

Un metodo 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

Puoi sostituire (goto IsFile)||(goto IsDir) con altri comandi batch:
(echo Is a File)||(echo is a Directory)

0
TechGuy

Sotto Windows 7 e XP, non riesco a farlo dire ai file rispetto alle dir su dischi mappati. Il seguente script:

 @ echo off 
 se esiste c:\temp\data.csv echo data.csv è un file 
 se esiste c:\temp\data.csv\echo data.csv è una directory 
 se esiste c:\temp\data.csv\nul echo data.csv è una directory 
 se esiste k:\temp\nonexistent.txt echo nonexistent.txt è un file 
 se esiste k:\temp\something .txt echo something.txt è un file 
 se esiste k:\temp\something.txt\echo something.txt è una directory 
 se esiste k:\temp\something.txt\nul echo something.txt è una directory 

produce:

 data.csv è un file 
 something.txt è un file 
 something.txt è una directory 
 something.txt è una directory 

Quindi, fai attenzione se il tuo script potrebbe essere alimentato con un percorso mappato o UNC. La soluzione pushd di seguito sembra essere la più infallibile.

0
user117529

Ok ... il trucco 'nul' non funziona se si usano le virgolette nei nomi, che rappresentano la maggior parte dei file con nomi di file lunghi o spazi.

Per esempio,

if exist "C:\nul" echo Directory

non fa niente, ma

if exist C:\nul echo Directory

lavori.

Alla fine sono arrivato a questo, che sembrava funzionare per tutti i casi:

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

o se puoi assicurarti di soddisfare tutti i requisiti per 'nul' una soluzione è:

if exist %~sf1\nul echo Directory

Inseriscili in un file batch come "test.bat" e fai "test.bat MyFile".

0
DrBB

Questo è il codice che uso nei miei file BATCH

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

`` `

0
gialloporpora