it-swarm.com.ru

Как проверить, является ли файл каталогом в пакетном скрипте?

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

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

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

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

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 в командной строке.

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

46
Dave Webb

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

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

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

78
Gerard

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

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

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

if exist %1\ echo Directory

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

12
Gerard

Вот скрипт, который использует 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
9
indiv

Это работает отлично

if exist "%~1\" echo Directory

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

6
Aziz

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

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

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

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

Результаты да на:

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

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

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

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

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

3
Samuel

Техника NUL работает только с именами файлов, совместимыми с 8.3.

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


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

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

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

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

Это DID НЕ работает:

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

Это DID НЕ работает:

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

3
pestophagous

Очень простой способ - проверить, существует ли ребенок.

Если у ребенка нет ребенка, команда exist вернет false.

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

У вас может быть ложный отрицательный результат, если у вас недостаточно прав доступа (я его не проверял).

2
Cedric

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

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

Я хотел бы опубликовать свой собственный функциональный скрипт на эту тему, надеюсь, что он будет полезен для кого-то однажды.

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

Этот пакетный скрипт проверяет, существует ли файл/папка и является ли он файлом или папкой.

Использование:

script.bat "ПУТЬ"

Код выхода (ов):

0: файл/папка не существует.

1: существует, и это папка.

3: существует, и это файл.

1
M. Jamal

Вот мое решение:

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 возвращает EXIT_FAILURE, когда указанный каталог не существует. И вы получили условную обработку символов , так что вы можете сделать, как показано ниже для этого.

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

:Error
CD %cd_backup%
1
Константин Ван

Если вы можете cd в него, это каталог:

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

Основываясь на этой статье под названием "Как пакетный файл может проверить существование каталога", это "не совсем надежно".

НО я только что проверил это:

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

и похоже на работу

1
Roman M

Вот мое решение после многих тестов, если они существуют, pushd, dir/AD и т.д.

@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
  • Работает с файлами без расширения
  • Работает с папками с именем folder.ext
  • Работает с UNC path
  • Он работает с полным путем в двойных кавычках или только с именем или именем файла.
  • Это работает, даже если у вас нет прав на чтение
  • Работает со справочными ссылками (соединениями).
  • Он работает с файлами, путь которых содержит ссылку на каталог.
0
Amr Ali

Одна из проблем, связанных с использованием метода %%~si\NUL, заключается в том, что существует вероятность, что он угадает неправильно. Возможно, имя файла будет сокращено до неправильного файла. Я не думаю, что %%~si разрешает имя файла 8.3, но угадывает его, но использует манипуляции со строками для сокращения пути к файлу. Я считаю, что если у вас есть похожие пути к файлам, это может не сработать.

Альтернативный метод:

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

Вы можете заменить (goto IsFile)||(goto IsDir) другими пакетными командами:
(echo Is a File)||(echo is a Directory)

0
TechGuy

Под Windows 7 и XP я не могу заставить их сравнивать файлы и каталоги на подключенных дисках. Следующий скрипт:

 @ echo off 
 если существует c:\temp\data.csv echo data.csv - это файл 
 если существует c:\temp\data.csv\echo data.csv - это каталог 
 если существует c:\temp\data.csv\nul echo data.csv - это каталог 
 если существует k:\temp\nonexistent.txt echo nonexistent.txt - это файл 
 если существует k:\temp\что-то .txt echo something.txt - это файл 
 если существует k:\temp\something.txt\echo something.txt - это каталог 
 если существует k:\temp\something.txt\nul echo нечто .txt - это каталог 

производит:

 data.csv - это файл 
thing.txt - это файл 
 some.txt - это каталог 
 Some.txt - это каталог 

Так что будьте осторожны, если ваш сценарий может быть указан сопоставленный или UNC-путь. Представленное ниже решение pushd кажется наиболее надежным.

0
user117529

Хорошо ... трюк 'nul' не работает, если вы используете кавычки в именах, которые составляют большинство файлов с длинными именами или пробелами.

Например,

if exist "C:\nul" echo Directory

ничего не делает, но

if exist C:\nul echo Directory

работает.

Я наконец придумал это, которое, казалось, работало для всех случаев:

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

или если вы можете быть уверены, что выполняете все требования для «nul», решение:

if exist %~sf1\nul echo Directory

Поместите их в командный файл, например, «test.bat» и выполните «test.bat MyFile».

0
DrBB

Это код, который я использую в моих пакетных файлах

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