ファイルがディレクトリかどうかを確認する方法はありますか?
変数にファイル名があります。 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
コマンドプロンプトで。
(注-上記の例は、バッチファイルで機能する形式です。コマンドラインで機能させるには、%%
with %
両方の場所で。)
これは動作します:
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
これは、子供たちが自宅で試しても安全です!
最近、上記とは異なるアプローチで失敗しました。彼らが過去に働いたことは確かです。おそらくここの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を囲む引用符は必要ありません。これにより、1年前の回答よりもキーストロークを1つ節約できます;-)
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
これは完全に機能します
if exist "%~1\" echo Directory
%〜1を使用して%1から引用符を削除し、最後にバックスラッシュを追加する必要があります。次に、全体を再びクートに入れます。
@ batchman61のアプローチのバリエーション(ディレクトリ属性の確認)。
今回は、外部の「検索」コマンドを使用します。
(ああ、&&
トリック。これは、長い退屈なIF ERRORLEVEL
構文。
@ECHO OFF
SETLOCAL EnableExtentions
ECHO.%~a1 | find "d" >NUL 2>NUL && (
ECHO %1 is a directory
)
Yes onを出力します。
これは機能し、スペースを含むパスも処理します:
dir "%DIR%" > NUL 2>&1
if not errorlevel 1 (
echo Directory exists.
) else (
echo Directory does not exist.
)
おそらく最も効率的ではありませんが、私の意見では他のソリューションよりも読みやすいでしょう。
「Documents and Settings」など、ディレクトリ名にスペースが含まれている場合、「NUL」テクニックの使用には多少の困難があると思います。
Windows XP Service Pack 2を使用し、%SystemRoot%\ system32\cmd.exeからcmdプロンプトを起動しています。
以下に、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
_
非常に簡単な方法は、子が存在するかどうかを確認することです。
子に子がない場合、exist
コマンドはfalseを返します。
IF EXIST %1\. (
echo %1 is a folder
) else (
echo %1 is a file
)
十分なアクセス権がない場合、いくつかの偽陰性が発生する可能性があります(テストしていません)。
私はこれを使用します:
if not [%1] == [] (
pushd %~dpn1 2> nul
if errorlevel == 1 pushd %~dp1
)
いつか誰かに役立つことを願って、このテーマに関する独自の関数スクリプトを投稿したいと思います。
@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 "PATH"
終了コード:
0:ファイル/フォルダーが存在しません。
1:存在し、それはフォルダーです。
3:存在し、ファイルです。
私のソリューションは次のとおりです。
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
指定されたディレクトリが存在しない場合、CD
はEXIT_FAILURE
を返します。そして、 条件付き処理シンボル を得たので、これについては以下のようにすることができます。
SET cd_backup=%cd%
(CD "%~1" && CD %cd_backup%) || GOTO Error
:Error
CD %cd_backup%
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
そしてそれはうまくいくようです
存在する場合、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
メソッドの使用に関する1つの問題は、間違った推測をする可能性があることです。ファイル名を間違ったファイルに短縮することは可能です。 %%~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)
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\something.txt echo something.txtはファイルです 存在する場合k:\ temp\something.txt\echo something.txtはディレクトリです if exist k:\ temp\something.txt\nul echo something.txtはディレクトリです
生成するもの:
data.csvはファイルです something.txtはファイルです something.txtはディレクトリです something.txtはディレクトリです
したがって、スクリプトにマップされたパスまたはUNCパスが与えられる可能性があることに注意してください。以下のpushdソリューションは、最も確実な方法のようです。
OK ...名前に引用符を使用すると、「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」を実行します。
これは、バッチファイルで使用するコードです
```
@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
`` `