Есть ли способ узнать, является ли файл каталогом?
У меня есть имя файла в переменной. В Perl я могу сделать это:
if(-d $var) { print "it's a directory\n" }
Есть ли способ узнать, является ли файл каталогом?
У меня есть имя файла в переменной. В Perl я могу сделать это:
if(-d $var) { print "it's a directory\n" }
Вы можете сделать это так:
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
в командной строке.
(Примечание: приведенный выше пример предназначен для работы в пакетном файле. Чтобы он работал в командной строке, замените %%
на %
в обоих местах.)
cmd
- person Aaron Thoma; 23.06.2012
Это работает:
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
Это безопасно, чтобы попробовать дома, дети!
*
!! (Также @GrantPeters)
- person Aaron Thoma; 23.06.2012
Недавно потерпел неудачу с различными подходами из вышеперечисленного. Совершенно уверен, что они работали в прошлом, возможно, здесь это связано с dfs. Теперь используйте атрибуты файлов и вырежьте первый символ
@echo off
SETLOCAL ENABLEEXTENSIONS
set ATTR=%~a1
set DIRATTR=%ATTR:~0,1%
if /I "%DIRATTR%"=="d" echo %1 is a folder
:EOF
%1
до полного пути к файлу/папке. Я должен использовать %~f1
. Он расширяет пути, такие как .
и ..
, до реального пути.
- person WesternGun; 09.02.2021
В дополнение к моему предыдущему предложению, я считаю, что это также работает:
if exist %1\ echo Directory
Кавычки вокруг %1 не нужны, потому что вызывающая сторона предоставит их. Это экономит одно нажатие клавиши по сравнению с моим ответом год назад ;-)
cmd
- person Aaron Thoma; 23.06.2012
Вот сценарий, который использует 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
\NUL
и ``.)
- person Aaron Thoma; 29.06.2012
`…`
.) « `` » должно было быть « \
». Я имел в виду подход добавления обратной косой черты в конце имени файла, например. предлагается здесь: stackoverflow.com/questions/138981/
- person Aaron Thoma; 05.12.2016
Это отлично работает
if exist "%~1\" echo Directory
нам нужно использовать %~1, чтобы удалить кавычки из %1 и добавить обратную косую черту в конце. Затем снова положите их целиком в котлеты.
cmd
- person Aaron Thoma; 23.06.2012
Вариант подхода @batchman61 (проверка атрибута Directory).
На этот раз я использую внешнюю команду «найти».
(О, и обратите внимание на трюк &&
. Это сделано для того, чтобы избежать длинного скучного синтаксиса IF ERRORLEVEL
.)
@ECHO OFF
SETLOCAL EnableExtensions
ECHO.%~a1 | find "d" >NUL 2>NUL && (
ECHO %1 is a directory
)
Выходы да вкл.:
Я думаю, что есть некоторые трудности с использованием метода «NUL», когда в имени каталога есть ПРОБЕЛЫ, такие как «Документы и настройки».
Я использую пакет обновления 2 для Windows XP и запускаю командную строку из %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
cmd
- person Aaron Thoma; 23.06.2012
Я использую это:
if not [%1] == [] (
pushd %~dpn1 2> nul
if errorlevel == 1 pushd %~dp1
)
Это работает, а также обрабатывает пути с пробелами в них:
dir "%DIR%" > NUL 2>&1
if not errorlevel 1 (
echo Directory exists.
) else (
echo Directory does not exist.
)
Вероятно, не самое эффективное, но, на мой взгляд, более легкое для чтения, чем другие решения.
cd
войти в него... конечно, запомните свой текущий каталог до set cwd=%cd%
, чтобы восстановить его позже...
- person Frank Nocke; 25.10.2015
CD
возвращает EXIT_FAILURE
, если указанный каталог не существует. И у вас есть символы условной обработки, так что вы можете сделать для этого, как показано ниже.
SET cd_backup=%cd%
(CD "%~1" && CD %cd_backup%) || GOTO Error
:Error
CD %cd_backup%
Очень простой способ — проверить, существует ли потомок.
Если у дочернего элемента нет ни одного дочернего элемента, команда exist
вернет значение false.
IF EXIST %1\. (
echo %1 is a folder
) else (
echo %1 is a file
)
У вас может быть ложный отрицательный результат, если у вас нет достаточных прав доступа (я не проверял).
Если вы можете 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%
Основано на этой статье под названием "Как можно пакетный файл проверяет наличие каталога», это «не совсем надежно».
НО я только что проверил это:
@echo off
IF EXIST %1\NUL goto print
ECHO not dir
pause
exit
:print
ECHO It's a directory
pause
и вроде работает
cmd
- person Aaron Thoma; 24.06.2012
Вот мое решение:
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
Я хотел бы опубликовать свой собственный сценарий функции на эту тему, надеюсь, что когда-нибудь он будет кому-то полезен.
@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: существует, и это файл.
В Windows 7 и XP я не могу заставить его различать файлы и каталоги на подключенных дисках. Следующий скрипт:
@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
производит:
data.csv is a file something.txt is a file something.txt is a directory something.txt is a directory
Так что будьте осторожны, если ваш сценарий может быть загружен сопоставленным или UNC-путем. Приведенное ниже решение pushd кажется наиболее надежным.
Это код, который я использую в своих пакетных файлах.
```
@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
```
Вот мое решение после многих тестов, если есть, 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
Одна проблема с использованием метода %%~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)
%~s1
не угадывает/манипулирует строкой с коротким именем файла, он правильно его разрешает. Как 2_
- person Aaron Thoma; 24.06.2012
Если ваша цель состоит в том, чтобы обрабатывать только каталоги, то это будет полезно.
Это взято из https://ss64.com/nt/for_d.html.
Пример... Перечислите все подпапки под папкой C:\Work\, имя которой начинается с «Пользователь»:
CD \Work FOR /D /r %%G in ("User*") DO Echo We found
FOR /D
or FOR /D /R
@echo off
cd /d "C:\your directory here"
for /d /r %%A in ("*") do echo We found a folder: %%~nxA
pause
Удалите /r
, чтобы углубиться только в одну папку. Переключатель /r
является рекурсивным и недокументированным в приведенной ниже команде.
Справка for /d
взята из команды for /?
FOR /D %variable IN (set) DO command [параметры команды]
Если набор содержит подстановочные знаки, то указывает соответствие именам каталогов, а не именам файлов.
Я тоже искал это недавно и наткнулся на решение, которое сработало для меня, но я не знаю каких-либо ограничений, которые у него есть (поскольку я еще не обнаружил их). Я считаю, что этот ответ по своей природе аналогичен ответу TechGuy выше, но я хочу добавить еще один уровень жизнеспособности. В любом случае, я добился большого успеха, расширив аргумент до полного пути к файлу, и я считаю, что вы должны использовать setlocal enableextensions
, чтобы это работало правильно.
Используя ниже, я могу определить, является ли файл каталогом или наоборот. Многое зависит от того, что на самом деле нужно пользователю. Если вы предпочитаете работать с конструкцией, ищущей errorlevel
по сравнению с &&
и ||
в своей работе, вы, конечно, можете это сделать. Иногда конструкция if для errorlevel
может дать вам немного больше гибкости, поскольку вам не нужно использовать команду GOTO
, которая иногда может нарушить условия вашей среды.
@Echo Off
setlocal enableextensions
Dir /b /a:D "%~f1" && Echo Arg1 is a Folder || Echo Arg1 is NOT a Folder
Dir /b /a:-D "%~f1" && Echo Arg1 is a File || Echo Arg1 is NOT a File
pause
Используя это, вы можете просто перетащить свои файлы на инструмент, который вы создаете, чтобы проанализировать их. И наоборот, если вы используете другие средства для прочесывания своей файловой структуры, и у вас уже есть файл, и вы не перетаскиваете его в пакетный файл, вы можете реализовать это:
@Echo Off
setlocal enableextensions
Dir /b /s "C:\SomeFolderIAmCombing\*" >"%~dp0SomeFiletogoThroughlater.txt"
For /f "Usebackq Delims=" %%a in ("%~dp0SomeFiletogoThroughlater.txt") do (
Call:DetectDir "%%a"
)
REM Do some stuff after parsing through Files/Directories if needed.
REM GOTO:EOF below is used to skip all the subroutines below.
REM Using ' CALL:DetectDir "%%a" ' with the for loop keeps the for
REM loop environment running in the background while still parsing the given file
REM in a clean environment where GOTO and other commmands do not need Variable Expansion.
GOTO:EOF
:DetectDir [File or Folder being checked]
REM Checks if Arg1 is a Directory. If yes, go to Dir coding. If not, go to File coding.
Dir /b /a:D "%~f1" && Echo Arg1 is a Folder & GOTO:IsDir || Echo Arg1 is NOT a Folder & GOTO:IsFile
REM Checks if Arg1 is NOT a Directory. If Yes, go to File coding. If not, go to Dir coding
Dir /b /a:-D "%~f1" && Echo Arg1 is a File & GOTO:IsFile || Echo Arg1 is NOT a File & GOTO:IsDir
:IsDir
REM Do your stuff to the Folder
GOTO:EOF
:IsFile
REM do your stuff to the File
GOTO:EOF
Разве мы не можем просто проверить это:
IF [%~x1] == [] ECHO Directory
Кажется, это работает для меня.
myfolder.fld
?
- person phuclv; 30.11.2016