提取树中文件夹的绝对/相对路径

提取树中文件夹的绝对/相对路径

我使用代码根据相对路径和/或文件名解析绝对路径为了从相对路径中提取绝对路径。

然而,我的问题是如何提取文件夹在树上但级别未知的相对/绝对路径。
假设以下文件夹树(是否有工具可以生成这些?):

- SomeFolder
---- FolderA
------------ FolderAA
------------ FolderAB
---- FolderB
------------ FolderBA
---------------- FolderBAA
---------------- FolderBAB
------------ FolderBB
---------------- FolderBBA
-------------------- FolderBBAA
-------------------- FolderBBAB
---------------- FolderBBB

所以我在,,FolderBBAAFolderBAAFolderAA
在的绝对路径之后FolderA

所以我正在寻找一个批处理函数,它会沿着树向上(只向上,不会向下)直到找到由给定名称命名的文件夹,然后将绝对文件夹返回到该文件夹​​。

如何为批处理文件编写这样的函数?

评论:请注意,查找的文件夹可能不是文件夹路径的一部分pwd。因此,在每个级别,该函数都应查找该级别的文件夹(但不查找其中的内容)。

伪代码

function [ relPathToFolder ] = SearchFolder( targetFolderName )

relPathToFolder = "None"; %<! Or any other value for the case not found
currFolder = "./";

% If in the currecnt working folder
currFolderItems = dir();
if targetFolderName in currFolderItems
  relPathToFolder = currFolder + targetFolderName;
  return;
end

% Going up until it is found
while(currFolder is not root)

  currFolder = relPathToFolder + "../";
  currFolderItems = dir(currFolder)

  if targetFolderName in currFolderItems
    relPathToFolder = currFolder + targetFolderName;
    return
  end

% If not found returning the not found string

end
  

答案1

我更新了答案,现在它还会在父文件夹和子文件夹的子文件夹中进行搜索。MaxLevel 是父文件夹的分隔符,这意味着不要比“父文件夹”更深

例如,如果您输入“Folder_F”并想要搜索名为“我的文件夹”的文件夹,而 MaxLevel 是“桌面”。它只会搜索“我的文件夹”直到桌面及其子文件夹,如果文件夹不存在,则返回“未找到”。MaxLevel 的原因是为了避免搜索时间过长,搜索时间可能包括整个驱动器等。

“C:\用户\ricar\桌面\文件夹_A\文件夹_B\文件夹_C\文件夹_D\文件夹_E\文件夹_F”

搜索存储在名为 GetParent 的函数中,因此您可以调用 Getparent。

@echo off
setLocal EnableDelayedExpansion
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"
mode con: cols=120 Lines=15
echo.
IF /i exist "%~1" (set "CurrentPath=%~1") else (set /p "CurrentPath=%BS% Please input the Path you want to verify: ")

:Start
set RelPath=
set RelPath2=
set Parent=
set AbsPath=

cls
echo.
echo  Current Path Analysed: "%CurrentPath%"
echo.
set /p "Parent=%BS% Please Input the Parent Folder: "
echo.
IF not Defined MaxLevel set /p "MaxLevel=%BS% Please Input Max Level Folder: "
pushd "%CurrentPath%"

Call :GetParent

:GetParent
cls
echo.
echo  Current Path Analysed: "%CurrentPath%"
echo.
echo  Searching for: "%Parent%"
echo.
echo  Max Level: "%Maxlevel%"
echo.
echo  Currently Scanning: "%CD%"
for /f "delims=" %%a in ('dir /s /b /ad ^&echo %CD%') do (                                              
                                                          IF /i "%CD:~-1%"=="\" (
                                                                                 echo.
                                                                                 Echo  Parent Folder not Found^^!
                                                                                 echo.
                                                                                 pause > nul | set /p="%BS% Press any key to continue..."
                                                                                 goto :End
                                                                                )
                                                          IF /i "%%~nxa"=="%Parent%" (
                                                                                      set "AbsPath=%%~dpnxa"
                                                                                      set "RelPath=!RelPath!"
                                                                                      set "RelPath2=!AbsPath:%CD%=!"
                                                                                      IF /i "!RelPath2!"=="" set "RelPath2=%%~nxa"& set "RelPath=..\!RelPath!"
                                                                                      set "RelPath=!RelPath!!RelPath2!"
                                                      set "RelPath=!RelPath:\\=\!"
                                                                                      echo.
                                                                                      echo  Relative path: "!RelPath!"
                                                                                      echo  Absolute path: "!AbsPath!"
                                                                                      echo.
                                                                                      pause > nul | set /p="%BS% Press any key to continue..."
                                                                                      goto :End
                                                                                     )
                                                          IF /i "%%~nxa"=="%Maxlevel%" (
                                                                                        echo.
                                                                                        Echo  Parent Folder not Found^^!
                                                                                        echo.
                                                                                        pause > nul | set /p="%BS% Press any key to continue..."
                                                                                        goto :End
                                                                                       )
                                                        )
cd ..
set "RelPath=..\%RelPath%"
goto :GetParent

:End
 echo.
echo.
set /p "Repeat=%BS% Go Again? (y) (n): "
If "%Repeat%"=="y" goto :Start
exit

https://i.imgur.com/6ezyd1u.gif

答案2

您可以使用解析器的工作方式将当前文件夹(%cd%)“拆分”为所需的基本路径并“注释掉”其余部分:

set folder=%cd:\SomeFolder\=\SomeFolder&REM %
echo %folder%

运行它来echo off观看“魔术”发生。

阅读输出set /?以了解子字符串替换的工作原理。

如果somefolder未找到,则不替换任何内容并返回当前工作文件夹。

编辑
我希望这次我理解正确了:

@echo off
setlocal
pushd "%~dp0"
:loop
  dir /ad "%~nx1" >nul 2>&1&& goto :found
  if "%cd:~3,1%" == "" echo not found & goto :eof
  cd ..
  set "rel=..\%rel%"

goto :loop
:found
set "found=%cd%\%~nx1"
echo absolute folder is "%found:\\=\%"
echo relative folder is "%rel%%~nx1"
popd
pause

查看是否FolderA是当前文件夹的子文件夹。如果不是,则向上移动一个文件夹并重复。如果您位于驱动器的根目录 ( ) 并且仍未找到它,则
中断循环。X:\

必须用 替换,因为\\它在根部给出了尾随反斜杠,但在其他任何地方都没有。\%CD%

搜索到的文件夹作为批处理文件的参数(也可以将其拖放到批处理文件上)。

答案3

  • /* EDIT

所以我正在寻找一个批处理函数...

以下是该版本的说明,认真回答,但假设我只会使用一次,您也可以那样使用它......

rem :: Your code where it is necessary to
rem :: find/define the folder in the variable %_dir%, add:

set^ "_up=..\" 
set^ "_cd=FolderA"

%:^(
for /d /r %_up% %%i in =;(*
     =;)do if /i "%%~nxi" == "%_cd%" =;(
          set^ "_dir=%%~fi" && goto %:^)
     =;)

=;<con: set^ "_up=%_up%..\" && goto %:^(

rem :: Your code where you continue from 
rem :: that point using the variable %_dir%
  • */ EDIT

%:^/
set^ "_up=..\"

%:^(
for /d /r %_up% %%i in =;(*
     =;)do if /i "%%~nxi" == "%~nx1" =;(
           set "_dir=%%~fi" && goto %:^)
     =;)

call set^ "_up=%_up%..\" && goto %:^(
  • 上面的函数使用循环来查找文件夹"FolderA",并定义_dir在参数中传递的文件夹的完整路径%~1,在:call %:^/ "FolderA"..

@echo off 

rem :: actual bat code :: 
rem :: actual bat code :: 
rem :: ............... ::
rem :: final code in your bat code :: 
rem :: if using setlocal, endlocal :: 

endlocal & exit /b || goto :eof 

rem :: its function starts below
rem :: just call function "folderName"   
rem :: call %:^/ ["Folder_Name_To_Find"] 

%:^/
set^ "_up=..\"

%:^(
for /d %%i in =;(%_up%*
    =;)do if /i "%%~nxi" == "%~nx1" =;(
          cd /d "%%~dpnxi" && goto %:^) 
        =;)

call set^ "_up=%_up%..\" && goto %:^(

%:^)
echo\Here I'm %CD% & exit /b 

1.在 var for 循环中将其..\(相对路径)定义为字符串,并在找不到文件夹名称后增加:_upfor /d ()

set^ "_up=..\"
for /Directory loop in (..\) 
              next loop in (..\..\)
                    next loop in (..\..\..\)
                              next loop in (so on...)
call set^ "_up=%_up%..\"  ==> ..\ + ..\

2.%1函数名称的参数是%~nx1,如果名称与当前文件夹名称匹配%%~nxi1, 你是“要走了” goto %:^)2...

if /i "%%~nxi" =="%~nx1" =;(
         cd /d "%%~dpnxi" && goto %:^)

观察:1甚至寻找文件夹~Name仅,使用循环文件会扩展%~nxi到名称 + 扩展名,但当涉及到循环文件夹,建议……

观察:2您也可以在此时退出函数...将此代码替换为exit /b

..)do if /i "%%~nxi" == "%~nx1" =;(
      cd /d "%%~dpnxi" && goto %:^) exit /b
    =;)

call set^ "_up=%_up%..\" && goto %:^(

%:^)
echo\Here I'm %CD% & exit /b 

  • 常规布局:

@echo off 

rem :: actual bat code :: 
rem :: actual bat code :: 
rem :: ............... ::
rem :: final code in your bat code :: 
rem :: if using setlocal, endlocal :: 

endlocal
exit /b || goto :eof 

rem :: its function starts below
rem :: just call function "folderName"   
rem :: call :main_loop ["Folder_Name_To_Find"] 

:main_loop
set "_up=..\"

:loop_folder
for /d %%i in (%_up%*) do (
     if /i "%%~nxi" == "%~nx1" (
         cd /d "%%~dpnxi"
         goto :loop_out
        )
    )

call set "_up=%_up%..\"
goto :loop_folder

:loop_out
echo\Here I'm %CD%
exit /b

...

%:^/
set^ "_up=..\"

%:^(
for /d /r %_up% %%i in =;(*)do if "%%~nxi"=="%~nx1" =;(
         cd /d "%%~fi" && set "_dir=%%~fi" && goto %:^)
     =;)

call set^ "_up=%_up%..\" && goto %:^(

%:^)
echo\Here I'm %CD%
...

:main_loop
set "_up=..\"

:loop_folder
for /d /r %_up% %%i in (*) do (
     if /i "%%~nxi" == "%~nx1" (
         cd /d "%%~dpnxi"
         set "_dir=%%~fi"
         goto :loop_out
        )
    )

call set "_up=%_up%..\"
goto :loop_folder

:loop_out
echo\Here I'm %CD%
exit /b

其他资源:

相关内容