wake-up-neo.com

Wie teste ich, ob ein File in einem Batch-Skript ist?

Gibt es eine Möglichkeit, herauszufinden, ob eine Datei ein Verzeichnis ist?

Ich habe den Dateinamen in einer Variablen. In Perl kann ich das machen:

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

Sie können es so machen:

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

Dies funktioniert jedoch nur für Verzeichnisse ohne Leerzeichen im Namen. Wenn Sie die Variable in Anführungszeichen setzen, um die Leerzeichen zu behandeln, wird sie nicht mehr funktionieren. Um Verzeichnisse mit Leerzeichen zu behandeln, konvertieren Sie den Dateinamen wie folgt in das kurze 8.3-Format:

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

Der %%~si konvertiert %%i in einen 8.3-Dateinamen. Um alle anderen Tricks anzuzeigen, die Sie mit FOR-Variablen ausführen können, geben Sie an einer Eingabeaufforderung HELP FOR ein.

(Hinweis - Das oben angegebene Beispiel hat das Format, um in einer Batchdatei zu arbeiten. Ersetzen Sie an beiden Stellen %% durch %, damit die Befehlszeile funktioniert.)

46
Dave Webb

Das funktioniert:

if exist %1\* echo Directory

Funktioniert mit Verzeichnisnamen, die Leerzeichen enthalten:

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

Beachten Sie, dass die Anführungszeichen erforderlich sind, wenn das Verzeichnis Leerzeichen enthält:

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

Kann auch ausgedrückt werden als:

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

Das können Sie sicher zu Hause versuchen, Kinder!

78
Gerard

Kürzlich mit anderen Ansätzen als oben gescheitert. Ziemlich sicher, dass sie in der Vergangenheit gearbeitet haben, vielleicht im Zusammenhang mit dfs hier. Verwenden Sie nun die Attribute files und schneiden Sie das erste Zeichen ab

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

Neben meinem vorherigen Angebot finde ich auch das funktioniert:

if exist %1\ echo Directory

Es sind keine Anführungszeichen um% 1 erforderlich, da der Anrufer sie liefern wird. Dies spart einen ganzen Tastendruck über meine Antwort vor einem Jahr ;-)

12
Gerard

Hier ist ein Skript, das FOR verwendet, um einen vollständig qualifizierten Pfad zu erstellen, und dann Pushd, um zu testen, ob der Pfad ein Verzeichnis ist. Beachten Sie, wie dies für Pfade mit Leerzeichen sowie für Netzwerkpfade funktioniert.

@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

Beispielausgabe mit der obigen als "isdir.bat" gespeichert:

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

Das funktioniert perfekt

if exist "%~1\" echo Directory

wir müssen% ~ 1 verwenden, um Anführungszeichen aus% 1 zu entfernen und am Ende einen Backslash hinzuzufügen. Dann füge das Ganze wieder in qutes ein.

6
Aziz

Eine Variante des Ansatzes von @ batchman61 (Überprüfung des Directory-Attributs).

Diesmal benutze ich einen externen 'find' Befehl.

(Oh, und beachten Sie den &&-Trick. Damit vermeiden Sie die langweilige IF ERRORLEVEL-Syntax.)

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

Ausgänge ja bei:

  • Verzeichnisse.
  • Verzeichnis symbolische Links oder Kreuzungen.
  • Defektes Verzeichnis symbolische Links oder Verknüpfungen. (Versucht nicht, Links aufzulösen.)
  • Verzeichnisse, für die Sie keine Leseberechtigung haben (z. B. "C:\System Volume Information")
3
Explorer09

Dies funktioniert und behandelt auch Pfade mit Leerzeichen:

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

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

Wahrscheinlich nicht die effizienteste, aber leichter lesbar als die anderen Lösungen meiner Meinung nach.

3
Samuel

Die NUL-Technik scheint nur mit 8.3-kompatiblen Dateinamen zu funktionieren.

(Mit anderen Worten, `D:\Documents and Settings` ist" schlecht "und` D:\DOCUME ~ 1` ist "gut")


Ich denke, es gibt einige Schwierigkeiten bei der Verwendung der "NUL" -Technik, wenn der Verzeichnisname Leerzeichen enthält, z. B. "Dokumente und Einstellungen".

Ich verwende Windows XP Service Pack 2 und starte die Eingabeaufforderung cmd über% SystemRoot%\system32\cmd.exe

Hier sind einige Beispiele dafür, was DID NICHT funktioniert und was für mich FUNKTIONIERT:

(Dies sind alles Demonstrationen, die "live" an einer interaktiven Eingabeaufforderung durchgeführt wurden. Ich denke, dass Sie die Dinge dort zum Laufen bringen sollten, bevor Sie versuchen, sie in einem Skript zu debuggen.)

Dies DID NICHT funktioniert:

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

Dies DID NICHT funktioniert:

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

Dies funktioniert (für mich):

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

Das funktioniert, aber es ist irgendwie albern, weil der Punkt bereits impliziert, dass ich mich in einem Verzeichnis befinde:

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

3
pestophagous

Eine sehr einfache Möglichkeit besteht darin, zu prüfen, ob das Kind existiert.

Wenn ein Kind kein Kind hat, gibt der Befehl exist den Wert false zurück.

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

Sie haben möglicherweise ein falsches Negativ, wenn Sie nicht über ein ausreichendes Zugriffsrecht verfügen (ich habe es nicht getestet).

2
Cedric

Ich benutze das:

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

Ich würde gerne ein eigenes Funktionsskript zu diesem Thema veröffentlichen, das hoffentlich eines Tages für jemanden nützlich sein könnte.

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

Dieses Batch-Skript überprüft, ob Datei/Ordner vorhanden ist und ob es sich um eine Datei oder einen Ordner handelt.

Verwendungszweck:

script.bat "PFAD"

Beendigungscode (s):

0: Datei/Ordner existiert nicht.

1: existiert und ist ein Ordner.

3: existiert und ist eine Datei.

1
M. Jamal

Hier ist meine Lösung:

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 gibt einen EXIT_FAILURE zurück, wenn das angegebene Verzeichnis nicht vorhanden ist. Und Sie haben bedingte Verarbeitungssymbole bekommen, so dass Sie dies wie folgt tun könnten.

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

:Error
CD %cd_backup%

Wenn Sie cd hinein können, ist es ein Verzeichnis:

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

Basierend auf diesem Artikel mit dem Titel "Wie kann eine Batchdatei das Vorhandensein eines Verzeichnisses testen" ist es "nicht ganz zuverlässig".

ABER ich habe das gerade getestet:

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

und es scheint zu funktionieren

1
Roman M

Hier ist meine Lösung nach vielen Tests mit 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
  • Es funktioniert mit Dateien, die keine Erweiterung haben
  • Es funktioniert mit Ordnern namens Ordner.ext
  • Es funktioniert mit UNC-Pfad
  • Es funktioniert mit doppelten Anführungszeichen oder nur mit dem Dateinamen oder dem Dateinamen.
  • Es funktioniert auch, wenn Sie keine Leseberechtigung haben
  • Es funktioniert mit Directory Links (Junctions).
  • Es funktioniert mit Dateien, deren Pfad eine Verzeichnisverknüpfung enthält.
0
Amr Ali

Ein Problem bei der Verwendung der %%~si\NUL-Methode besteht darin, dass die Möglichkeit besteht, dass sie falsch schätzt. Es ist möglich, einen Dateinamen auf die falsche Datei zu verkürzen. Ich glaube nicht, dass %%~si den 8.3-Dateinamen auflöst, aber errät es, aber mit Hilfe der String-Manipulation kann der Dateipfad verkürzt werden. Ich glaube, wenn Sie ähnliche Dateipfade haben, funktioniert es möglicherweise nicht.

Eine alternative Methode:

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

Sie können (goto IsFile)||(goto IsDir) durch andere Stapelbefehle ersetzen:
(echo Is a File)||(echo is a Directory)

0
TechGuy

Unter Windows 7 und XP kann ich Dateien und Verzeichnisse auf zugeordneten Laufwerken nicht erkennen. Das folgende Skript:

 @ echo aus 
 wenn vorhanden c:\temp\data.csv echo data.csv ist eine Datei 
 falls vorhanden c:\temp\data.csv\echo data.csv ist ein Verzeichnis 
 wenn vorhanden c:\temp\data.csv\nul echo data.csv ist ein Verzeichnis 
 falls vorhanden k:\temp\nonexistent.txt echo nonexistent.txt ist eine Datei .txt echo etwas.txt ist eine Datei 
 wenn vorhanden k:\temp\etwas.txt\echo etwas.txt ist ein Verzeichnis 
 wenn vorhanden k:\temp\etwas.txt\nul echo etwas.txt ist ein Verzeichnis 

produziert:

 data.csv ist eine Datei 
 Etwas.txt ist eine Datei 
 Etwas.txt ist ein Verzeichnis 
 Etwas.txt ist ein Verzeichnis 

Seien Sie also vorsichtig, wenn Ihr Skript möglicherweise einen zugeordneten oder UNC-Pfad erhält. Die Pushd-Lösung unten scheint die narrensicherste zu sein.

0
user117529

Ok ... der 'nul'-Trick funktioniert nicht, wenn Sie Anführungszeichen in Namen verwenden, was die meisten Dateien mit langen Dateinamen oder Leerzeichen berücksichtigt.

Zum Beispiel,

if exist "C:\nul" echo Directory

tut nichts, aber

if exist C:\nul echo Directory

funktioniert.

Ich kam schließlich dazu, was für alle Fälle zu funktionieren schien:

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

oder wenn Sie sicher sein können, dass Sie alle Anforderungen für 'nul' erfüllen, ist eine Lösung:

if exist %~sf1\nul echo Directory

Legen Sie diese in eine Batchdatei wie 'test.bat' und führen Sie 'test.bat MyFile' aus.

0
DrBB

Dies ist der Code, den ich in meinen BATCH-Dateien verwende

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