Est-il possible de savoir si un fichier est un répertoire?
J'ai le nom du fichier dans une variable. En Perl, je peux faire ceci:
if(-d $var) { print "it's a directory\n" }
Vous pouvez le faire comme ça:
IF EXIST %VAR%\NUL ECHO It's a directory
Toutefois, cela ne fonctionne que pour les répertoires sans espaces dans leurs noms. Lorsque vous ajoutez des guillemets autour de la variable pour gérer les espaces, celle-ci cesse de fonctionner. Pour gérer les répertoires avec des espaces, convertissez le nom du fichier au format 8.3 court comme suit:
FOR %%i IN (%VAR%) DO IF EXIST %%~si\NUL ECHO It's a directory
Le %%~si
convertit %%i
en un nom de fichier 8.3. Pour voir toutes les autres astuces que vous pouvez effectuer avec les variables FOR
, entrez HELP FOR
à l'invite de commande.
(Remarque - l'exemple donné ci-dessus est conçu pour fonctionner dans un fichier de commandes. Pour le faire fonctionner en ligne de commande, remplacez %%
par %
aux deux endroits.)
Cela marche:
if exist %1\* echo Directory
Fonctionne avec les noms de répertoire contenant des espaces:
C:\>if exist "c:\Program Files\*" echo Directory
Directory
Notez que les guillemets sont nécessaires si le répertoire contient des espaces:
C:\>if exist c:\Program Files\* echo Directory
Peut aussi être exprimé comme:
C:\>SET D="C:\Program Files"
C:\>if exist %D%\* echo Directory
Directory
C'est sûr d'essayer à la maison, les enfants!
Récemment échoué avec des approches différentes de celles mentionnées ci-dessus. Bien sûr, ils ont travaillé dans le passé, peut-être lié à DFS ici. Maintenant, en utilisant les attributs files et coupez le premier caractère
@echo off
SETLOCAL ENABLEEXTENSIONS
set ATTR=%~a1
set DIRATTR=%ATTR:~0,1%
if /I "%DIRATTR%"=="d" echo %1 is a folder
:EOF
Suite à mon offre précédente, je trouve que cela fonctionne également:
if exist %1\ echo Directory
Il ne faut pas de guillemets autour de% 1 car l'appelant les fournira . Cela évite toute une frappe sur ma réponse il y a un an ;-)
Voici un script qui utilise FOR pour créer un chemin complet, puis pushd pour vérifier si le chemin est un répertoire. Remarquez comment cela fonctionne pour les chemins contenant des espaces, ainsi que les chemins réseau.
@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
Exemple de sortie avec l’enregistrement ci-dessus enregistré sous le nom "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
Cela fonctionne parfaitement
if exist "%~1\" echo Directory
nous devons utiliser% ~ 1 pour supprimer les guillemets de% 1 et ajouter une barre oblique inverse à la fin. Puis mettez-le à nouveau en entier.
Une variante de l'approche de @ batchman61 (vérification de l'attribut Annuaire).
Cette fois, j'utilise une commande externe 'find'.
(Oh, et notez l'astuce &&
. C'est pour éviter la syntaxe fastidieuse de IF ERRORLEVEL
.)
@ECHO OFF
SETLOCAL EnableExtentions
ECHO.%~a1 | find "d" >NUL 2>NUL && (
ECHO %1 is a directory
)
Sorties oui sur:
Cela fonctionne et gère également les chemins contenant des espaces:
dir "%DIR%" > NUL 2>&1
if not errorlevel 1 (
echo Directory exists.
) else (
echo Directory does not exist.
)
Probablement pas la plus efficace mais plus facile à lire que les autres solutions à mon avis.
Je pense qu'il est difficile d'utiliser la technique "NUL" lorsqu'il y a des espaces dans le nom du répertoire, tels que "documents et paramètres".
J'utilise Windows XP service pack 2 et lance l'invite cmd à partir de% SystemRoot%\system32\cmd.exe.
Voici quelques exemples de ce que DID NE fonctionne PAS et de ce qui fonctionne pour moi:
(Ce sont toutes des démonstrations effectuées "en direct" dans une invite interactive. Je suppose que vous devriez faire en sorte que les choses fonctionnent avant d'essayer de les déboguer dans un script.)
This DID NOT work:
D:\Documents and Settings>if exist "D:\Documents and Settings\NUL" echo yes
This DID NOT work:
D:\Documents and Settings>if exist D:\Documents and Settings\NUL echo yes
Cela fonctionne (pour moi):
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
[[Regardez juste ici !!!! ]]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
Cela fonctionne, mais c'est un peu idiot, car le point implique déjà que je suis dans un répertoire:
D:\Documents and Settings>if exist .\NUL echo yes
Un moyen très simple est de vérifier si l'enfant existe.
Si un enfant n'a pas d'enfant, la commande exist
renverra false.
IF EXIST %1\. (
echo %1 is a folder
) else (
echo %1 is a file
)
Vous pouvez avoir un faux négatif si vous n’avez pas le droit d’accès suffisant (je ne l’ai pas testé).
J'utilise ceci:
if not [%1] == [] (
pushd %~dpn1 2> nul
if errorlevel == 1 pushd %~dp1
)
J'aimerais publier mon propre script de fonction sur ce sujet dans l'espoir d'être utile pour quelqu'un un jour.
@pushd %~dp1
@if not exist "%~nx1" (
popd
exit /b 0
) else (
if exist "%~nx1\*" (
popd
exit /b 1
) else (
popd
exit /b 3
)
)
Ce script batch vérifie si le fichier/dossier existe et s'il s'agit d'un fichier ou d'un dossier.
Utilisation:
script.bat "CHEMIN"
Code (s) de sortie:
0: le fichier/dossier n'existe pas.
1: existe et c'est un dossier.
3: existe et c'est un fichier.
Voici ma solution:
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
CD
renvoie un EXIT_FAILURE
lorsque le répertoire spécifié n'existe pas. Et vous avez des symboles de traitement conditionnel , vous pouvez donc faire comme ci-dessous pour cela.
SET cd_backup=%cd%
(CD "%~1" && CD %cd_backup%) || GOTO Error
:Error
CD %cd_backup%
Si vous pouvez y ajouter cd
, il s'agit d'un répertoire:
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%
Basé sur cet article intitulé "Comment un fichier de commandes peut-il vérifier l’existence d’un répertoire", c’est "pas entièrement fiable".
MAIS je viens de tester ceci:
@echo off
IF EXIST %1\NUL goto print
ECHO not dir
pause
exit
:print
ECHO It's a directory
pause
et cela semble fonctionner
Voici ma solution après de nombreux tests avec if exist, 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
Un problème lié à l’utilisation de la méthode %%~si\NUL
est qu’il est possible qu’elle devine mal. Il est possible d'avoir un nom de fichier raccourci vers le mauvais fichier. Je ne pense pas que %%~si
résolve le nom de fichier 8.3, mais le devine, mais utilisez une manipulation de chaîne pour raccourcir le chemin du fichier. Je crois que si vous avez des chemins de fichiers similaires, cela peut ne pas fonctionner.
Une méthode alternative:
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
Vous pouvez remplacer (goto IsFile)||(goto IsDir)
par d'autres commandes batch:(echo Is a File)||(echo is a Directory)
Sous Windows 7 et XP, je ne peux pas le faire dire des fichiers ou des répertoires sur des lecteurs mappés. Le script suivant:
@ echo off s'il existe c:\temp\data.csv echo data.csv est un fichier s'il existe c:\temp\data.csv\echo data.csv est un répertoire s'il existe c:\temp\data.csv\nul echo data.csv est un répertoire s'il existe k:\temp\nonexistent.txt echo nonexistent.txt est un fichier .__ s'il existe k:\temp\quelque chose .txt echo quelque chose.txt est un fichier s'il existe k:\temp\quelque chose.txt\echo quelque chose.txt est un répertoire s'il existe k:\temp\quelque chose.txt\nul echo quelque chose.txt est un répertoire
produit:
data.csv est un fichier quelque chose.txt est un fichier quelque chose.txt est un répertoire quelque chose.txt est un répertoire
Alors méfiez-vous si votre script peut être alimenté par un chemin mappé ou UNC. La solution pushd ci-dessous semble être la plus infaillible.
Ok ... l'astuce "nulle" ne fonctionne pas si vous utilisez des guillemets dans les noms, ce qui représente la plupart des fichiers avec des noms de fichiers longs ou des espaces.
Par exemple,
if exist "C:\nul" echo Directory
ne fait rien, mais
if exist C:\nul echo Directory
travaux.
J'ai finalement trouvé cela, qui semblait fonctionner pour tous les cas:
for /f %%i in ('DIR /A:D /B %~dp1 ^| findstr /X /c:"%~nx1"') do echo Directory
ou si vous pouvez vous assurer que vous répondez à toutes les exigences pour «nul», la solution est la suivante:
if exist %~sf1\nul echo Directory
Mettez-les dans un fichier de commandes comme "test.bat" et faites "test.bat MonFichier".
C'est le code que j'utilise dans mes fichiers 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
`` `