-1

I use the code Resolve Absolute Path from Relative Path and / or File Name in order to extract absolute path from relative path.

Yet my question is how to extract the relative / absolute path of a folder up the tree but at unknown level.
Assume the following folder tree (Is there a tool to generate those?):

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

So I am at, FolderBBAA, FolderBAA or FolderAA.
I am after the absolute path for FolderA.

So I'm looking for a Batch Function which goes up (Just up, it doesn't go down) the tree until it finds the folder named by a given name and then returns the absolute folder to the folder.

How could one write such function for a Batch File?

Remark: Pay attention that the folder looked for might not be part of the path to the pwd folder. So at each level the function should look on the folders of that level (But not inside them).

Pseudo Code

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
  

21
  • Think of the general case, I just want to go up in the tree and look for a folder. I don't know at which level the folder I'm looking for is (How many times to go up, maybe one, two, etc...).
    – Royi
    May 22, 2021 at 13:09
  • I'd better have it in the same format as the function I linked above. I'd like to use it within existing batch file.
    – Royi
    May 22, 2021 at 14:02
  • So sorry, but this is not bat/cmd and I don’t know how can I help you. Talves you're using a pseudo code that only you understand, I don't know what language it is. Forgive me for take your time...
    – Io-oI
    May 24, 2021 at 5:13
  • 1
    @It Wasn't Me: Talves you're using a pseudo code ??????? LOL May 24, 2021 at 10:28
  • 1
    It is difficult to answer when your edits (and comments) change the original question.
    – Io-oI
    May 29, 2021 at 16:30

3 Answers 3

2

I updated the answer, now it also searches in sub-folders of the parent and child folders. MaxLevel is a delimiter for parent folders meaning don't go any deeper than that "parent folder"

For example if you have "Folder_F" as input and want to search for a folder called "my folder" and MaxLevel is "Desktop". It would only search for "my folder" up to Desktop and it's sub-folders and return a "Not Found" if the folder wasn't there. The reason for MaxLevel is to avoid very long search time that might include whole drives and more.

"C:\Users\ricar\Desktop\Folder_A\Folder_B\Folder_C\Folder_D\Folder_E\Folder_F"

The search is stored in a funcion called GetParent so you can do a call 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

12
  • Could it be in a form like stackoverflow.com/a/33404867? Namely it is under :call block and sets a variable which can be used later?
    – Royi
    May 25, 2021 at 4:16
  • Does the code looks for all sub folders of the current folder it looks at?
    – Royi
    May 26, 2021 at 3:47
  • It depends on what subfolder you drag & drop to the batch. It actually searches only for parent folders not for subfolders. Basically it does a "CD.." (go up 1 level), than a "CD" (check current parent),CD,CD..,CD,CD....and so on.IF the current parent is the folder you are searching for it shows the path. I add that call: & save in variable part later... May 26, 2021 at 8:28
  • Have you looked on the cases I posted in the question? The pseudo code? It is not only if the folder name is in the path of the current folder.
    – Royi
    May 26, 2021 at 8:30
  • Yes I looked but apparently I didn't fully understand it. So it should search for a given Folder in Parent folders and in Subfolders? May 26, 2021 at 8:38
2

You can use the way, the parser works to "split" the current folder (%cd%) into the desired base path and "commenting out" the rest:

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

Run it with echo off to watch the "magic" happen.

Read the output of set /? to learn how the substring substitution works.

If somefolder isn't found, nothing is replaced and it returns the current working folder.

EDIT
I hope I understood you correctly this time:

@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

See if FolderA is a child of the current folder. If not, go up one folder and repeat.
Break the loop, if you are at the root of the drive (X:\) and still haven't found it.

The replacement of \\ with \ is necessary, because %CD% gives a trailing backslash at the root, but not anywhere else.

The searched folder is given as a parameter to the batchfile (also drop/drag onto the batchfile works).

10
  • Am I mistaken to understand your code only looks if the searched for folder is part of the path? But ic could be a sub folder of a folder in the path and the code won't find it.
    – Royi
    May 26, 2021 at 3:47
  • Your question says only "up the path" (straight line). If we have to look into "sibling folders" at any point, this changes the question completely. Please clarify (preferably in the question itself)
    – Stephan
    May 26, 2021 at 6:41
  • How can you find FolderA from FolderBBAA without looking at sub folders? I said you only go up and look for folders at that level, not going down again into them. That was how the question was phrased from the beginning (If you want, it only looks one level down each time it goes up).
    – Royi
    May 26, 2021 at 7:44
  • 1
    Maybe you are mistaken "Subfolders" with "Parent"....users (Parent) -> username (current Folder) -> Desktop (subfolder).. May 26, 2021 at 8:48
  • Ah - I (mis)understood SomeFolder to be a fixed known name.
    – Stephan
    May 26, 2021 at 15:59
1
  • /* EDIT

So I'm looking for a Batch Function which goes up...

The follow below of this edition, attentive to answer, but assuming that I will use it only once, you can also use it that way...

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 %:^(
  • Above a function that uses a loop to find folder "FolderA" and define _dir with the full path to your folder passed in the argument %~1, in: 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. Define this ..\ (relative path) to _up string in a var for loop and increment after for /d () not find your folde name:

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

2. Your argument %1 to function name is %~nx1 and if the name matches to the current folder name %%~nxi1, you are "goo to go" goto %:^)2...

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

Obs.: 1 Even looking for folder ~Name only, the use with looped files expands %~nxi to Name + eXtension, but when it comes to looped folders, it is recommended...

Obs.: 2 You can also exit the function at this point... replace this code to 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 

  • Conventional layout:

@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

Additional Resources:

7
  • If you could give me a single solution in the form of something like: pastebin.com/f7Xy0mjD. Something I can call and it returns the relative path to the folder (Or NONE if not find).
    – Royi
    May 22, 2021 at 20:22
  • @Royi Good point, i've not think in 'if not find' condition.. I will see in + 1-2 h ..
    – Io-oI
    May 22, 2021 at 20:25
  • @Royi without having at least the name of a folder above to take it as a limit, the search / scan to affirm that (Folder_A) it does not exist, will go / go through many folders to the root
    – Io-oI
    May 23, 2021 at 4:13
  • @Royi Would it be valid to assume the folder where the bat itself is (%~f0) as the above folder as the search limit for searching the target folder, and if not finding it can say that the target folder does not exist?
    – Io-oI
    May 23, 2021 at 4:36
  • I think it is OK to go up until you reach the root. If you want, you can set a parameter to the number of times to go up (Input Parameter).
    – Royi
    May 23, 2021 at 4:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .