ファイルがバッチスクリプトのディレクトリであるかどうかをテストする方法

StackOverflow https://stackoverflow.com/questions/138981

質問

ファイルがディレクトリかどうかを確認する方法はありますか?

変数にファイル名があります。 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を入力します。

(注-上記の例はバッチファイルで動作する形式です。コマンドラインで動作させるには、両方の場所で%%%に置き換えます。)

他のヒント

これは動作します:

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

上記を<!> quot; isdir.bat <!> quot;として保存したサンプル出力:

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から引用符を削除し、最後にバックスラッシュを追加する必要があります。次に、全体をもう一度クートに入れます。

NULテクニックは、8.3準拠のファイル名でのみ機能するようです。

(つまり、 `D:\ Documents and Settings`は<!> quot; bad <!> quot;で、` D:\ DOCUME〜1`は<!> quot; good <!> quot;です)


<!> quot; NUL <!> quot;の使用には多少の困難があると思います。 <!> quot; Documents and Settings。<!> quot;

など、ディレクトリ名にスペースが含まれる場合のtecnique

Windows XP Service Pack 2を使用し、%SystemRoot%\ system32 \ cmd.exeからcmdプロンプトを起動しています

以下は、DIDが機能しないものと、私にとって機能するものの例です。

(これらはすべて、デモで<!> quot; live <!> quot;対話型プロンプトで行われます。スクリプトでデバッグする前に、そこで動作させる必要があると思います。)

この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

これは機能し、スペースを含むパスも処理します:

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

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

おそらく最も効率的ではないが、私の意見では他のソリューションよりも読みやすい。

@ batchman61のアプローチのバリエーション(ディレクトリ属性の確認)。

今回は、外部の「検索」コマンドを使用します。

(ああ、&&トリックに注意してください。これは、退屈なIF ERRORLEVEL構文を避けるためです。)

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

yesを出力します:

  • ディレクトリ。
  • ディレクトリシンボリックリンクまたはジャンクション。
  • 破損ディレクトリのシンボリックリンクまたはジャンクション。 (リンクを解決しようとしません。)
  • 読み取り権限のないディレクトリ(例:<!> quot; C:\ System Volume Information <!> quot;)

これを使用:

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

非常に簡単な方法は、子が存在するかどうかを確認することです。

子に子がない場合、existコマンドはfalseを返します。

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

十分なアクセス権を持っていない場合、偽陰性が発生する可能性があります(テストしていません)。

この記事に基づく<!> quot;バッチファイルでディレクトリの存在をテストする方法<!> quot; <!> quot;完全に信頼できる<!> quot;ではありません。

しかし、私はこれをテストしました:

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

そしてそれは動作するようです

ここに私の解決策があります:

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できる場合、それはディレクトリです:

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%

いつか誰かに役立つことを願って、このテーマに関する独自の関数スクリプトを投稿したいと思います。

@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 <!> quot; PATH <!> quot;

終了コード:

0:ファイル/フォルダーが存在しません。

1:存在し、それはフォルダーです。

3:存在し、ファイルです。

CDは、指定されたディレクトリが存在しない場合にEXIT_FAILUREを返します。そして、 条件付き処理シンボル を取得したので、このために以下のようにすることができます。

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

:Error
CD %cd_backup%

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

produces:

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

`` `

わかりました...名前に引用符を使用すると、「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」を実行します。

存在する場合、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パスで動作します
  • 二重引用符で囲まれたフルパスまたはdirnameまたはfilenameのみで機能します。
  • 読み取り権限がない場合でも機能します
  • ディレクトリリンク(ジャンクション)で動作します。
  • パスにディレクトリリンクが含まれるファイルで動作します。

%%~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)

これだけでテストすることはできません:

IF [%~x1] == [] ECHO Directory

私にとってはうまくいくようです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top