IT박스

배치 파일 : 상대 경로가있는 디렉토리의 모든 파일 나열

itboxs 2020. 12. 9. 07:57
반응형

배치 파일 : 상대 경로가있는 디렉토리의 모든 파일 나열


Windows 배치 파일 관련 : 목록의 현재 (또는 검색) 디렉토리에 상대적인 경로를 포함하여 특정 디렉토리 및 하위 디렉토리에있는 모든 파일 (또는 특정 유형의 모든 파일)을 나열하는 방법이 있습니까?

예를 들어 현재 디렉토리와 하위 디렉토리에있는 모든 .txt 파일을 전체 경로와 함께 원하면 다음을 수행 할 수 있습니다.

for /r . %%g in (*.txt) do echo %%g >> C:\temp\test.txt

또는

dir *.txt /b /s >> C:\temp\test.txt

그리고 나는 다음과 같은 것을 얻을 것이다

C:\test\Doc1.txt
C:\test\subdir\Doc2.txt
C:\test\subdir\Doc3.txt

만약 내가한다면

for /r . %%g in (*.txt) do echo %%~nxg >> C:\temp\test.txt

나는 다음과 같은 것을 얻을 것이다

Doc1.txt
Doc2.txt
Doc3.txt

그러나 내가 정말로 원하는 것은 :

Doc1.txt
subdir\Doc2.txt
subdir\Doc3.txt

가능합니까?

내 게시물이 너무 혼란 스러우면 기본적으로 현재 디렉토리에 상대적인 경로를 사용하여 Linux CLI에서 재귀 적 으로 파일을 나열 하지만 Windows에만 해당됩니다.


현재 디렉토리의 문자 길이를 가져와 절대 목록 에서 제거 할 수 있습니다.

setlocal EnableDelayedExpansion
for /L %%n in (1 1 500) do if "!__cd__:~%%n,1!" neq "" set /a "len=%%n+1"
setlocal DisableDelayedExpansion
for /r . %%g in (*.log) do (
  set "absPath=%%g"
  setlocal EnableDelayedExpansion
  set "relPath=!absPath:~%len%!"
  echo(!relPath!
  endlocal
)

디렉토리 트리를 반복하고 상대 파일 경로를 나열하는 가장 간단한 (빠른 것은 아님) 방법은 FORFILES 를 사용하는 입니다.

forfiles /s /m *.txt /c "cmd /c echo @relpath"

상대 경로는 다음과 같이 선행 .\으로 인용 됩니다.

".\Doc1.txt"
".\subdir\Doc2.txt"
".\subdir\Doc3.txt"


따옴표를 제거하려면 :

for /f %%A in ('forfiles /s /m *.txt /c "cmd /c echo @relpath"') do echo %%~A


따옴표와 선행을 제거하려면 다음을 수행하십시오 .\.

setlocal disableDelayedExpansion
for /f "delims=" %%A in ('forfiles /s /m *.txt /c "cmd /c echo @relpath"') do (
  set "file=%%~A"
  setlocal enableDelayedExpansion
  echo !file:~2!
  endlocal
)

또는 지연된 확장을 사용하지 않고

for /f "tokens=1* delims=\" %%A in (
  'forfiles /s /m *.txt /c "cmd /c echo @relpath"'
) do for %%F in (^"%%B) do echo %%~F

이 대답은 등호 ( =)가 포함 된 루트 경로에서는 제대로 작동하지 않습니다 . (이를 지적 해 주신 @dbenham에게 감사드립니다.)


수정 됨 :! @dbenham (감사합니다!)이 다시 발견 한을 포함하는 경로 문제를 수정했습니다 .

길이를 계산하고 부분 문자열을 추출하는 대신 다른 접근 방식을 사용할 수 있습니다.

  • 루트 경로를 저장하십시오.

  • 파일 경로에서 루트 경로를 지 웁니다.

내 시도는 다음과 같습니다.

@ECHO OFF
SETLOCAL DisableDelayedExpansion
SET "r=%__CD__%"
FOR /R . %%F IN (*) DO (
  SET "p=%%F"
  SETLOCAL EnableDelayedExpansion
  ECHO(!p:%r%=!
  ENDLOCAL
)

The r variable is assigned with the current directory. Unless the current directory is the root directory of a disk drive, it will not end with \, which we amend by appending the character. (No longer the case, as the script now reads the __CD__ variable, whose value always ends with \ (thanks @jeb!), instead of CD.)

In the loop, we store the current file path into a variable. Then we output the variable, stripping the root path along the way.


Of course, you may write a recursive algorithm in Batch that gives you exact control of what you do in every nested subdirectory:

@echo off
set mypath=
call :treeProcess
goto :eof

:treeProcess
setlocal
for %%f in (*.txt) do echo %mypath%%%f
for /D %%d in (*) do (
    set mypath=%mypath%%%d\
    cd %%d
    call :treeProcess
    cd ..
)
endlocal
exit /b

@echo on>out.txt
@echo off
setlocal enabledelayedexpansion
set "parentfolder=%CD%"
for /r . %%g in (*.*) do (
  set "var=%%g"
  set var=!var:%parentfolder%=!
  echo !var! >> out.txt
)

참고URL : https://stackoverflow.com/questions/8385454/batch-files-list-all-files-in-a-directory-with-relative-paths

반응형