Come verificare se un file è una directory in un file batch?
-
02-07-2019 - |
Domanda
C'è un modo per scoprire se un file è una directory?
Ho il nome del file in una variabile.In Perl che posso fare questo:
if(-d $var) { print "it's a directory\n" }
Soluzione
Si può fare in questo modo:
IF EXIST %VAR%\NUL ECHO It's a directory
Tuttavia, questo funziona solo per le directory senza spazi nei nomi.Quando si aggiunge citazioni giro variabile per gestire gli spazi che smetterà di funzionare.Per gestire le directory con spazi, di convertire il nome del file di breve formato 8.3, come segue:
FOR %%i IN (%VAR%) DO IF EXIST %%~si\NUL ECHO It's a directory
Il %%~si
converte %%i
un nome di file 8.3.Per vedere tutti gli altri trucchi che si possono eseguire con FOR
le variabili entrano HELP FOR
al prompt dei comandi.
(Nota - l'esempio dato sopra è il formato per lavorare in un file batch.Per farlo dalla riga di comando, sostituire il %%
con %
in entrambi i luoghi.)
Altri suggerimenti
Funziona:
if exist %1\* echo Directory
Funziona con nomi di directory che contengono spazi:
C:\>if exist "c:\Program Files\*" echo Directory
Directory
Nota 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!
Recentemente fallito con approcci diversi da quelli sopra. Abbastanza sicuro che hanno lavorato in passato, forse legato al dfs qui. Ora utilizza attributi di file 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
Oltre alla mia precedente offerta, trovo che funzioni anche:
if exist %1\ echo Directory
Non sono necessarie virgolette intorno a% 1 perché il chiamante le fornirà. Ciò consente di risparmiare un'intera sequenza di tasti sulla mia risposta di un anno fa ;-)
Ecco uno script che utilizza FOR per creare un percorso completo, quindi pushd per verificare se il percorso è una directory. Notare come funziona per i percorsi con spazi e per 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
Output di esempio con quanto sopra 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
Funziona perfettamente
if exist "%~1\" echo Directory
dobbiamo usare% ~ 1 per rimuovere le virgolette da% 1 e aggiungere una barra rovesciata alla fine. Quindi rimetti tutto in qutes.
La tecnica NUL sembra funzionare solo su nomi di file conformi a 8.3.
(In altre parole, `D: \ Documents and Settings` è " bad " e` D: \ DOCUME ~ 1` è " good ")
Penso che ci sia qualche difficoltà nell'uso del " NUL " tecnica in presenza di SPAZI nel nome della directory, ad esempio " Documents and Settings. "
Sto utilizzando Windows XP Service Pack 2 e avvio il prompt cmd da% SystemRoot% \ system32 \ cmd.exe
Ecco alcuni esempi di cosa NON ha funzionato e cosa NON FUNZIONA per me:
(Queste sono tutte dimostrazioni fatte " live " 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 proprio 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 implica già che sono in una directory:
D:\Documents and Settings>if exist .\NUL echo yes
Funziona e gestisce anche i 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.
Una variante dell'approccio di @ batchman61 (controllo dell'attributo Directory).
Questa volta uso un comando 'trova' esterno.
(Oh, e nota il trucco &&
. Questo per evitare la noiosa sintassi IF ERRORLEVEL
noiosa.)
@ECHO OFF
SETLOCAL EnableExtentions
ECHO.%~a1 | find "d" >NUL 2>NUL && (
ECHO %1 is a directory
)
Output sì su:
- Rubriche.
- Collegamenti simbolici o incroci della directory. Collegamenti simbolici o incroci della directory spezzata . (Non tenta di risolvere i collegamenti.)
- Directory su cui non si dispone dell'autorizzazione di lettura (ad es. " C: \ System Volume Information ")
Uso questo:
if not [%1] == [] (
pushd %~dpn1 2> nul
if errorlevel == 1 pushd %~dp1
)
Un modo molto semplice è verificare se il bambino esiste.
Se un figlio non ha figli, il comando exist
restituirà false.
IF EXIST %1\. (
echo %1 is a folder
) else (
echo %1 is a file
)
Potresti avere dei falsi negativi se non hai il diritto di accesso sufficiente (non l'ho provato).
Basato su questo articolo intitolato " Come può un file batch verificare 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
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
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%
Vorrei pubblicare il mio script di funzione 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 verifica l'esistenza di file / cartella e se si tratta di un file o di una cartella.
Utilizzo:
script.bat " PATH "
Codici di uscita:
0: il file / la cartella non esiste.
1: esiste ed è una cartella.
3: esiste ed è un file.
CD
restituisce un EXIT_FAILURE
quando la directory specificata non esiste. E hai simboli di elaborazione condizionale , quindi puoi fare come segue per questo.
SET cd_backup=%cd%
(CD "%~1" && CD %cd_backup%) || GOTO Error
:Error
CD %cd_backup%
In Windows 7 e XP, non riesco a dire file e directory su unità mappate. Il seguente script:
@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
produce:
data.csv is a file something.txt is a file something.txt is a directory something.txt is a 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ù sicura.
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
`` `
Ok ... il trucco 'nul' non funziona se usi le virgolette nei nomi, che rappresentano la maggior parte dei file con nomi o spazi lunghi.
Ad esempio,
if exist "C:\nul" echo Directory
non fa nulla, ma
if exist C:\nul echo Directory
opere.
Alla fine ho pensato a questo, che sembrava funzionare in 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
Mettili in un file batch come 'test.bat' e fai 'test.bat MyFile'.
Ecco la mia soluzione dopo molti test con if, 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 che non hanno estensione
- Funziona con cartelle denominate folder.ext
- Funziona con il percorso UNC
- Funziona con il percorso completo tra virgolette doppie o solo con il nome dir o solo 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 alla directory.
Un problema con l'utilizzo del metodo %%~si\NUL
è che esiste la possibilità che indovini errato. È possibile avere un nome file abbreviato nel file sbagliato. Non credo che %%~si
risolva il nome del file 8.3, ma indovino, ma usando la manipolazione delle stringhe per abbreviare il percorso del 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)
Non possiamo semplicemente provare con questo:
IF [%~x1] == [] ECHO Directory
Sembra funzionare per me.