Как проверить, является ли файл каталогом в пакетном скрипте? - PullRequest
63 голосов
/ 26 сентября 2008

Есть ли способ узнать, является ли файл каталогом?

У меня есть имя файла в переменной. В Perl я могу сделать это:

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

Ответы [ 22 ]

80 голосов
/ 23 сентября 2009

Это работает:

if exist %1\* echo Directory

Работает с именами каталогов, которые содержат пробелы:

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

Обратите внимание, что кавычки необходимы, если каталог содержит пробелы:

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

Может также быть выражено как:

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

Это безопасно попробовать дома, дети!

47 голосов
/ 26 сентября 2008

Вы можете сделать это так:

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

Однако это работает только для каталогов без пробелов в их именах. Когда вы добавите кавычки вокруг переменной для обработки пробелов, она перестанет работать. Для обработки каталогов с пробелами преобразуйте имя файла в короткий формат 8.3 следующим образом:

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

%%~si преобразует %%i в имя файла 8.3. Чтобы увидеть все другие приемы, которые вы можете выполнить с помощью FOR переменных, введите HELP FOR в командной строке.

(Обратите внимание - приведенный выше пример в формате для работы в командном файле. Чтобы он работал в командной строке, замените %% на % в обоих местах.)

43 голосов
/ 16 сентября 2010

Недавно произошел сбой при разных подходах, описанных выше. Совершенно уверен, что они работали в прошлом, может быть, связаны с DFS здесь. Теперь используя атрибуты файлов и вырезайте первый символ

@echo off
SETLOCAL ENABLEEXTENSIONS
set ATTR=%~a1
set DIRATTR=%ATTR:~0,1%
if /I "%DIRATTR%"=="d" echo %1 is a folder
:EOF
12 голосов
/ 02 октября 2010

В дополнение к моему предыдущему предложению, я считаю, что это также работает:

if exist %1\ echo Directory

Никаких кавычек около% 1 не требуется, потому что вызывающий абонент их предоставит. Это спасло меня от нажатия всего моего ответа год назад; -)

9 голосов
/ 27 сентября 2008

Вот скрипт, который использует FOR для построения полного пути, а затем pushd, чтобы проверить, является ли путь каталогом. Обратите внимание, как это работает для путей с пробелами, а также для сетевых путей.

@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

Пример вывода с вышеупомянутым, сохраненным как "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
6 голосов
/ 27 сентября 2011

Это прекрасно работает

if exist "%~1\" echo Directory

нам нужно использовать% ~ 1, чтобы удалить кавычки из% 1 и добавить обратную косую черту в конце. Затем снова положите все в кавычки.

3 голосов
/ 10 февраля 2015

Это работает, а также обрабатывает пути с пробелами в них:

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

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

Вероятно, не самый эффективный, но легче читаемый, чем другие решения на мой взгляд.

3 голосов
/ 10 марта 2015

Вариант подхода @ batchman61 (проверка атрибута Directory).

На этот раз я использую внешнюю команду 'find'.

(О, и обратите внимание на трюк &&. Это позволяет избежать длинного скучного синтаксиса IF ERRORLEVEL.)

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

Выходы да включены:

  • Директории.
  • Каталог символических ссылок или соединений.
  • Сломан символьные ссылки каталога или соединения. (Не пытается разрешить ссылки.)
  • Каталоги, для которых у вас нет разрешения на чтение (например, "C: \ System Volume Information")
3 голосов
/ 26 сентября 2008

Кажется, что метод NUL работает только с 8.3 совместимыми именами файлов.

(Другими словами, `D: \ Documents and Settings` -" плохо ", а` D: \ DOCUME ~ 1` - "хорошо")


Я думаю, что есть некоторая сложность в использовании метода "NUL", когда в имени каталога есть ПРОСТРАНСТВА, такие как "Документы и настройки".

Я использую Windows XP с пакетом обновления 2 и запускаю команду cmd из% SystemRoot% \ system32 \ cmd.exe

Вот несколько примеров того, что НЕ работает и что работает для меня:

(Это все демонстрации, выполненные «вживую» в интерактивном режиме. Я полагаю, что вы должны заставить их работать там, прежде чем пытаться отлаживать их в сценарии.)

Это НЕ РАБОТАЛО:

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

Это НЕ РАБОТАЛО:

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

Это работает (для меня):

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

Это работает, но глупо, потому что точка уже означает, что я нахожусь в каталоге:

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

2 голосов
/ 08 сентября 2010

Я использую это:

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