Development Tip

파일이 배치 스크립트의 디렉토리인지 테스트하는 방법은 무엇입니까?

yourdevel 2020. 11. 12. 20:25
반응형

파일이 배치 스크립트의 디렉토리인지 테스트하는 방법은 무엇입니까?


파일이 디렉토리인지 알아내는 방법이 있습니까?

변수에 파일 이름이 있습니다. 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변환 %%i8.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 년 전의 내 대답에 대해 하나의 전체 키 입력을 저장합니다 ;-)


다음은 FOR를 사용하여 정규화 된 경로를 만든 다음 해당 경로가 디렉터리인지 여부를 테스트하기 위해 푸시하는 스크립트입니다. 네트워크 경로뿐만 아니라 공백이있는 경로에 대해 어떻게 작동하는지 확인하십시오.

@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에서 따옴표를 제거하고 끝에 백 슬래시를 추가해야합니다. 그런 다음 전체를 qute에 다시 넣으십시오.


NUL 기술은 8.3 호환 파일 이름에서만 작동하는 것 같습니다.

(즉,`D : \ Documents and Settings`는 "bad"이고`D : \ DOCUME ~ 1`은 "good"입니다.)


"문서 및 설정"과 같이 디렉토리 이름에 공백이 있으면 "NUL"기술을 사용하는 데 약간의 어려움이 있다고 생각합니다.

Windows XP 서비스 팩 2를 사용하고 있으며 % SystemRoot % \ system32 \ cmd.exe에서 cmd 프롬프트를 시작합니다.

다음은 작동하지 않는 것과 나를 위해 작동하는 것의 몇 가지 예입니다.

(이들은 모두 대화 형 프롬프트에서 "실시간"으로 수행되는 데모입니다. 스크립트에서 디버깅을 시도하기 전에 작업을 수행해야한다고 생각합니다.)

이것은 작동하지 않았습니다.

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


이것은 작동하며 공백이있는 경로도 처리합니다.

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
)

출력 예 :

  • 디렉토리.
  • 디렉토리 기호 링크 또는 접합.
  • 손상된 디렉토리 기호 링크 또는 접합. (링크를 해결하려고하지 마십시오.)
  • 읽기 권한이없는 디렉토리 (예 : "C : \ System Volume Information")

나는 이것을 사용한다 :

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
)

충분한 액세스 권한이 없으면 거짓 음성이 나타날 수 있습니다 (테스트하지 않았습니다).


"배치 파일이 디렉토리의 존재를 어떻게 테스트 할 수 있는가"라는 제목 의이 기사 에 따르면 "전적으로 신뢰할 수있는 것은 아닙니다".

하지만 방금 테스트했습니다.

@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 "PATH"

종료 코드 :

0 : 파일 / 폴더가 존재하지 않습니다.

1 : 존재하고 폴더입니다.

3 : 존재하고 파일입니다.


CD returns an EXIT_FAILURE when the specified directory does not exist. And you got conditional processing symbols, so you could do like the below for this.

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

:Error
CD %cd_backup%

Under Windows 7 and XP, I can't get it to tell files vs. dirs on mapped drives. The following script:

@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

So beware if your script might be fed a mapped or UNC path. The pushd solution below seems to be the most foolproof.


This is the code that I use in my BATCH files

```
@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

```


Here is my solution after many tests with if exist, pushd, dir /AD, etc...

@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
  • It works with files that have no extension
  • It works with folders named folder.ext
  • It works with UNC path
  • It works with double-quoted full path or with just the dirname or filename only.
  • It works even if you don't have read permissions
  • It works with Directory Links (Junctions).
  • It works with files whose path contains a Directory Link.

One issue with using %%~si\NUL method is that there is the chance that it guesses wrong. Its possible to have a filename shorten to the wrong file. I don't think %%~si resolves the 8.3 filename, but guesses it, but using string manipulation to shorten the filepath. I believe if you have similar file paths it may not work.

An alternative method:

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

You can replace (goto IsFile)||(goto IsDir) with other batch commands:
(echo Is a File)||(echo is a Directory)


Can't we just test with this :

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

It seems to work for me.

참고URL : https://stackoverflow.com/questions/138981/how-to-test-if-a-file-is-a-directory-in-a-batch-script

반응형