Чи є спосіб дізнатись, чи файл є каталогом?
У мене є ім’я файлу у змінній. У 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
<Ctrl> + <Shift> + <Enter> mklink /d LinkDir .
<Enter> cd LinkDir
<Enter> if exist regedt32.exe\nul echo File erroneously detected as Directory
<Enter>rd .
Це працює:
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)
Нещодавно не вдалося з різними підходами, описаними вище. Цілком впевнені, що вони працювали раніше, можливо, пов’язані з dfs тут. Тепер використовуємо атрибути файлів і вирізаємо спочатку символ
@echo off
SETLOCAL ENABLEEXTENSIONS
set ATTR=%~a1
set DIRATTR=%ATTR:~0,1%
if /I "%DIRATTR%"=="d" echo %1 is a folder
:EOF
На додаток до моєї попередньої пропозиції, я вважаю, що це також працює:
if exist %1\ echo Directory
Котирування близько% 1 не потрібні, оскільки абонент надасть їх. Це економить одне ціле натискання клавіші за мою відповідь року тому ;-)
cmd
<Ctrl> + <Shift> + <Enter> mklink /d LinkDir .
<Enter> cd LinkDir
<Enter> if exist regedt32.exe\ echo File erroneously detected as Directory
<Enter>rd .
Ось сценарій, який використовує 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
і `` прийомів.)
`…`
вбудованого форматування коду.) `` '' Мало бути «\
». Я мав на увазі підхід додавання зворотної скісної риски в кінці імені файлу, наприклад, запропонований тут: stackoverflow.com/questions/138981/…
Це працює чудово
if exist "%~1\" echo Directory
нам потрібно використовувати% ~ 1, щоб видалити лапки з% 1 і додати зворотну скісну риску в кінці. Потім знову поставте thw цілим у qutes.
cmd
<Ctrl> + <Shift> + <Enter> mklink /d LinkDir .
<Enter> cd LinkDir
<Enter> if exist "regedt32.exe\" echo File erroneously detected as Directory
<Enter>rd .
Варіація підходу @ batchman61 (перевірка атрибута Directory).
Цього разу я використовую зовнішню команду "знайти".
(О, і зверніть увагу на &&
фокус. Це для того, щоб уникнути довгого нудного IF ERRORLEVEL
синтаксису.)
@ECHO OFF
SETLOCAL EnableExtensions
ECHO.%~a1 | find "d" >NUL 2>NUL && (
ECHO %1 is a directory
)
Виходи так:
Я думаю, є певні труднощі із використанням техніки "NUL", коли в назві каталогу є ПРОСТОРИ, наприклад "Документи та налаштування".
Я використовую пакет оновлень 2 для Windows XP і запускаю командний рядок 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
cmd
<Ctrl> + <Shift> + <Enter> mklink /d LinkDir .
<Enter> cd LinkDir
<Enter> if exist regedt32.exe\nul echo File erroneously detected as Directory
<Enter>rd .
Це працює, а також обробляє шляхи з пробілами в них:
dir "%DIR%" > NUL 2>&1
if not errorlevel 1 (
echo Directory exists.
) else (
echo Directory does not exist.
)
Напевно, не найефективніший, але легший для читання, ніж інші рішення, на мій погляд.
cd
це зробити ... звичайно, згадайте свій поточний каталог, перш ніж set cwd=%cd%
відновити пізніше ...
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
<Ctrl> + <Shift> + <Enter> mklink /d LinkDir .
<Enter> cd LinkDir
<Enter> if exist "regedt32.exe\NUL" echo File erroneously detected as Directory
<Enter>rd .
Ось моє рішення:
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 вимкнено якщо існує 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 \ something.txt echo something.txt - це файл якщо існує k: \ temp \ something.txt \ echo something.txt - це каталог якщо існує k: \ temp \ something.txt \ nul echo something.txt - це каталог
виробляє:
data.csv - це файл something.txt - це файл something.txt - це каталог something.txt - це каталог
Тому будьте обережні, якщо ваш скрипт може бути поданий на карту або UNC-шлях. Наведене нижче рішення видається найбільш надійним.
Це код, який я використовую у своїх файлах BATCH
```
@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
він не "вгадує" / не маніпулює коротким ім'ям файлу, він вирішує його правильно. Подобаєтьсяdir /x
Якщо ваша мета полягає лише в обробці каталогів, це буде корисно.
Це взято з https://ss64.com/nt/for_d.html
Приклад ... Перелічіть кожну підпапку під папкою C: \ Work \, яка має ім'я, що починається на "Користувач":
CD \Work FOR /D /r %%G in ("User*") DO Echo We found
FOR /D
або 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% змінна IN (встановити) DO команда [команда-параметри]
Якщо набір містить символи підстановки, тоді вказується відповідність іменам каталогів замість імен файлів.
Чи не можемо ми просто перевірити це:
IF [%~x1] == [] ECHO Directory
Здається, це працює для мене.
myfolder.fld
?