Как проверить, является ли путь файлом или каталогом в пакетном файле Windows?
Я искал здесь, нашел кого-то с помощью этого
set is_dir=0
for %%i in ("%~1") do if exist "%%~si"\nul set is_dir=1
но не сработало, когда %1==c:\this is a file with spaces.csproj
, тест все еще успешен, что означает, что он все еще будет рассматриваться как папка!!!
Кто-нибудь знает ответ, я думаю, это очень распространенная проблема, и Windows существует уже много-много лет, у нее должно быть очень простое решение....
7 ответов
Я знаю if exist path\nul
тест для папки, используемой для работы на MS-DOS. Я не знаю, было ли это сломано с введением длинных имен файлов.
я знал это if exist "long path\nul"
не работает в пакетном режиме Windows. До сегодняшнего дня я не осознавал, что if exist path\nul
работает на Vista и выше, пока путь в короткой форме 8.3.
Оригинальный код работает на Vista. Кажется, что он должен работать и на XP, но я считаю, что мешает следующая ошибка XP: Пакетный параметр%~s1 дает неверное короткое имя 8.3.
Исходный код не нуждается в цикле FOR, он может просто использовать %~s1
Вот вариант, который полностью классифицирует путь как INVALID, FILE или FOLDER. Он работает на Vista, но не работает на XP из-за %~s1
ошибка. Я не уверен, как это работает на MS-DOS.
РЕДАКТИРОВАТЬ 2015-12-08: Есть ряд ситуаций Windows, где это не удается
@echo off
if not exist "%~1" ( set "type=INVALID" ) else if exist %~s1\nul ( set "type=FOLDER" ) else ( set "type=FILE" )
@echo "%~1" = %type%
Я считаю, что этот вариант будет работать практически со всеми версиями пакета Microsoft, включая MS-DOS и XP. (очевидно, он не будет работать на ранних версиях DOS, которые не поддерживают PUSHD)
@echo off
if exist "%~1" (2>nul pushd "%~1" && (popd&set "type=FOLDER") || set "type=FILE" ) else set "type=INVALID"
echo "%~1" = %type%
ОБНОВЛЕНИЕ 2014-12-26
Я уверен, что следующее будет работать на всех версиях Windows начиная с XP, но я тестировал только на Win 7.
Редактировать 2015-12-08: Это может произойти сбой на сетевых дисках, потому что тест папки может ложно сообщить о файле как о папке
@echo off
if exist %1\ (
echo %1 is a folder
) else if exist %1 (
echo %1 is a file
) else (
echo %1 does not exist
)
ОБНОВЛЕНИЕ 2015-12-08
Наконец - тест, который действительно должен работать на любой версии Windows начиная с XP, в том числе с сетевыми дисками и путями UNC
for /f "tokens=1,2 delims=d" %%A in ("-%~a1") do if "%%B" neq "" (
echo %1 is a folder
) else if "%%A" neq "-" (
echo %1 is a file
) else (
echo %1 does not exist
)
Я просто попробовал таким образом. Надеюсь это поможет.
@ECHO OFF
SET CURR_DIR=%CD%
SET IS_DIR=0
CD %1%
IF "%ERRORLEVEL%"=="0" SET IS_DIR=1
CD %CURR_DIR%
ECHO IS DIRECTORY %IS_DIR%
Выход:
D:\Work\Stand alone Java classes>test.bat D:\Work\Training
IS DIRECTORY 1
D:\Work\Stand alone Java classes>test.bat D:\Work\Training\SRT.txt
The directory name is invalid.
IS DIRECTORY 0
Параметр /ad для команды "dir" выводит список папок, параметр /b для пустых. Предполагая, что у вас есть проверки на наличие файла, используйте:
dir /ad /b ChangeThisToYourFilename 1> NUL 2> NUL
if %ERRORLEVEL% EQU 0 (
echo is a file
) else (
echo is NOT a file
)
Это решение объединяет расширение параметра атрибута файла (%~a1
) с извлечением переменной подстроки (%variable:~0,1%
):
@ECHO OFF
CALL :is_directory C:\Windows
CALL :is_directory C:\MinGW\share\doc\mingw-get\README
CALL :is_directory C:\$Recycle.Bin
CALL :is_directory "C:\Documents and Settings"
CALL :is_directory "%LOGONSERVER%\C$\Users\All Users"
GOTO :EOF
:is_directory
SETLOCAL
SET file_attribute=%~a1
IF "%file_attribute:~0,1%"=="d" (
ECHO %file_attribute% %1 is a directory
) ELSE (
ECHO %file_attribute% %1 is NOT a directory
)
ENDLOCAL
GOTO :EOF
Выход:
d-------- C:\Windows is a directory
--a------ C:\MinGW\share\doc\mingw-get\README is NOT a directory
d--hs---- C:\$Recycle.Bin is a directory
d--hs---l "C:\Documents and Settings" is a directory
d--hs---l "\\MYCOMPUTER\C$\Users\All Users" is a directory
Для 1 вкладыша:
dir /a:d /b C:\Windows 2>&1 | findstr /i /n /c:"File Not Found">nul && (@echo. Im a file) || (@echo. Im a folder)
например, изменить C:\Windows
в C:\Windows\Notepad.exe
-Извините, Арун, Дбенхэм, не читал вашу! Такой же как..
Ранее я использовал "\nul"
метод, но долгое время я использовал "\*"
проверить, является ли существующая спецификация файла папкой или файлом. Насколько я знаю, он работает на всех версиях Windows, от Windows 95 (и, возможно, более ранних версий) до всех текущих версий Windows.
Итак, как и в случае с другими методами, сначала проверьте, существует ли файл. Затем, чтобы увидеть, является ли это папкой, протестируйте ее с помощью: if exist "%fspec%\*"
:
if not exist "%fspec%" goto :NotExistOrInvalid
rem "%fspec%" is "Valid" and is either a "Folder", or a "File".
if exist "%fspec%\*" goto :IsValidAndIsAFolder
rem "%fspec%" is a "File" (a "Regular File" or a Shortcut/Link).
goto :IsValidAndIsAFile
Например:
set "fspec=XYZ:%perlpath%"
if not exist "%fspec%" echo "%fspec%": Invalid or not found && rem Invalid, goto :NotExistOrInvalid
set "fspec=%perlpath%"
if not exist "%fspec%" echo "%fspec%": Invalid or not found && rem goto :NotExistOrInvalid
rem "%fspec%" Is a "Valid" filespec and is either a "Folder", or a "File".
if exist "%fspec%\*" (echo "%fspec%" is a "Folder".) else echo "%fspec%" is a "File".
set "fspec=%perlpath%\perl.exe"
if not exist "%fspec%" echo "%fspec%": Invalid or not found && rem Invalid, goto :NotExistOrInvalid
rem "%fspec%" Is a "Valid" filespec and is either a "Folder", or a "File".
if exist "%fspec%\*" (echo "%fspec%" is a "Folder".) else echo "%fspec%" is a "File".
Выход для этого:
"XYZ:F:\usr\perl\bin": Invalid or not found
"F:\usr\perl\bin" is a "Folder".
"F:\usr\perl\bin\perl.exe" is a "File".
Я думаю, что не хватает определения функции в официальной документации, на самом деле я ожидаю, что базовая встроенная функция cmd.exe должна вернуться, если файл или папка с указанным именем существует в сценарии, однако разделение файла и папки цель более высокой функции рычага, например, dir... следовательно, эти требования могут быть выполнены с помощью других средств, очень многих... в моем случае сейчас, в 2023 году, я заканчиваю папки, например, в \;
@echo off
IF EXIST %OneDriveCommercial%\desktop\ (
copy "%appdata%\Microsoft\Windows\Start Menu\Programs\Work Resources (RADC)\*.lnk" "%OneDriveCommercial%\desktop\"
echo Copied RDAC to %OneDriveCommercial%\desktop
) else (
copy "%appdata%\Microsoft\Windows\Start Menu\Programs\Work Resources (RADC)\*.lnk" "%userprofile%\desktop"
echo Copied RDAC to %userprofile%\desktop
)