Loop over folder string and parse out last folder name

后端 未结 13 1403
-上瘾入骨i
-上瘾入骨i 2020-12-03 05:39

I need to grab the folder name of a currently executing batch file. I have been trying to loop over the current directory using the following syntax (which is wrong at prese

相关标签:
13条回答
  • 2020-12-03 06:12

    I modified answer given by @Jonathan, since it did not work for me in a batch file, but this below does work, and also supports folders with spaces in it.:

    for %%a in ("%CD%") do set LastFolder=%%~nxa
    echo %LastFolder%
    

    This takes the current directory and echoes the last, deepest folder, as in below example, if the folder is this:

    C:\Users\SuperPDX\OneDrive\Desktop Environment\
    

    The batch code echoes this: Desktop Environment

    0 讨论(0)
  • 2020-12-03 06:14

    To return to the original poster's issue:

    For example, given the following path: C:\Folder1\Folder2\Folder3\Archive.bat I would expect to parse out the value 'Folder3'.

    The simple solution for that is:

    for /D %%I in ("C:\Folder1\Folder2\Folder3\Archive.bat\..") do echo parentdir=%%~nxI
    

    will give 'Folder3'. The file/path does not need to exist. Of course, .... for the parent's parent dir, or ...... for the one above that (and so on) work too.

    0 讨论(0)
  • 2020-12-03 06:16

    In batch files in the FOR command you'll need to prepend %whatever with an extra % (e.g. %%whatever).

    'echo %~p0' will print the currently directory of the batch file.

    0 讨论(0)
  • 2020-12-03 06:16

    This is what we had in the end (little bit more crude and can only go so deep :)

    @echo off
    for /f "tokens=1-10 delims=\" %%A in ('echo %~p0') do (
        if NOT .%%A==. set new=%%A
        if NOT .%%B==. set new=%%B
        if NOT .%%C==. set new=%%C
        if NOT .%%D==. set new=%%D
        if NOT .%%E==. set new=%%E
        if NOT .%%F==. set new=%%F
        if NOT .%%G==. set new=%%G
        if NOT .%%H==. set new=%%H
        if NOT .%%I==. set new=%%I
        if NOT .%%J==. set new=%%J
    )
    
    @echo %new%
    
    0 讨论(0)
  • 2020-12-03 06:19

    This question's a little old, but I've looked for a solution more than once so here's a completely new take on it that I've just put together.

    The trick is that we take the desired path, back up one level to create a folder mask for substitution and then replace the folder mask with nothing.

    To test it, simple copy and paste into a command script (.cmd) in any directory, then run it. It will spit out only the deepest directory you're currently in.

    Notes:

    • Replace %~dp0 with whatever path you like (as it is, it will return the deepest folder the batch file is run from. This is not the same as %cd%.)
    • When specifying the 'pathtofind' variable ensure there are no quotes e.g. c:\some path and not "c:\some path".
    • The original idea for folder masking is mine
    • Spaces in the path are no problem
    • Folder depth is not a problem
    • It was made possible by the genius of this batch scripting tip http://www.dostips.com/DtCodeBatchFiles.php#Batch.FindAndReplace

    Hope this helps someone else.

    @echo off
    set pathtofind=%~dp0
    if not exist %pathtofind% echo Path does not exist&pause>nul&goto :eof
    
    cd /d %pathtofind%
    set path1=%cd%
    cd ..
    set path2=%cd%
    
    call set "path3=%%path1:%path2%\=%%"
    
    echo %path3%
    
    pause>nul
    
    0 讨论(0)
  • 2020-12-03 06:19

    I don't know if it's the version of windows I'm on (win2k3), but the FOR loop isn't giving me anything useful for trying to iterate through a single string. According to my observation (and the FOR /? info) you get one iteration for each line of input to FOR, and there is no way to change this to iterate within a line. You can break into multiple tokens for a given line, but it is only one invocation of the FOR loop body.

    I do think the CALL :LABEL approach in these answers does a great job. Something I didn't know until looking at this was that ";" and "," are both recognized as argument separators. So once you replace backslashes with semicolons, you can call your label and iterate through with SHIFT.

    So working off of what is posted by others here, I have the below solution. Instead of grabbing the last folder name, I actually wanted to find everything up until some known directory name.. this is what is implemented below.

    @echo off
    if "%1"=="" goto :USAGE
    
    set FULLPATH=%~f1
    set STOPDIR=%2
    set PATHROOT=
    
    :: Replace backslashes with semicolons
    set FULLPATH=%FULLPATH:\=;%
    
    :: Iterate through path (the semicolons cause each dir name to be a new argument)
    call :LOOP %FULLPATH%
    goto :EOF
    
    :LOOP
    
    ::Exit loop if reached the end of the path, or the stop dir
    if "%1"=="" (goto :EOF)
    if "%1"=="%STOPDIR%" (goto :EOF)
    
    ::If this is the first segment of the path, set value directly. Else append.
    if not defined PATHROOT (set PATHROOT=%1) else (set PATHROOT=%PATHROOT%\%1)
    
    ::shift the arguments - the next path segment becomes %i
    SHIFT
    
    goto :LOOP
    
    :USAGE
    echo Usage:
    echo %~0 ^<full path to parse^> ^<dir name to stop at^>
    echo E.g. for a command:
    echo %~0 c:\root1\child1\child2 child2
    echo The value of c:\root1\child1 would be assigned to env variable PATHROOT
    
    0 讨论(0)
提交回复
热议问题