-2

I have no idea how to get what described here using an Win CMD batch script:

pseudo-code

set aPath=C:\just\a\long\path\to\a\file\in\the\file\system
set aDir=file
... some logic here 
echo %result%

Should print

C:\just\a\long\path\to\a\file

It should stop at the first occurrence found, but it would be nice to specify also the occurence (optional).

ONLY Windows CMD SOLUTIONS ARE WELCOME no Powershell code nor external tools, please. I'm looking for a pure Windows CMD solution.

Compo
  • 36,585
  • 5
  • 27
  • 39
Max
  • 2,508
  • 3
  • 26
  • 44
  • 2
    With `setlocal EnableExtensions EnableDelayedExpansion` in batch file above the line `for /F "delims=|" %%I in ("!apath:\%aDir%\=\%aDir%|!") do endlocal & set "result=%%I"`, the output is as wanted by you. This works only if `aDir` does not contain `=`. If `aDir` is not found case insensitive in `aPath`, `result` is equal `aPath` like on `aDir` being last directory in `aPath` if `aPath` does not end with a backslash. – Mofi Aug 29 '19 at 20:36

3 Answers3

0

I'm not quite sure to what you refer with occurence

Using a shuffle approach and self modifying code to get the dir levels

:: Q:\Test\2019\08\29\SO_57717256.cmd
@Echo off & Setlocal EnableDelayedExpansion

set "aPath=C:\just\a\long\path\to\a\file\in\the\file\system"
set "aDir=file"
echo aPath = %aPath%
echo aDir  = %aDir%

::... some logic here 
set "intermediate=!apath:*%aDir%=!"
set "result=!aPath:%intermediate%=!"

:: and some vodoo there ;-)
Set i=0
Set "aPath=%aPath:\="&Set /a i+=1&Set "aPath[!i!]=%"

echo result= %result%

for /l %%L in (1,1,%i%) Do if "%aDir%"=="!aPath[%%L]!" (
    echo aPath[%%L] = !aPath[%%L]! ^<^<^< matches aDir %aDir%
) else (
    echo aPath[%%L] = !aPath[%%L]!
)

Sample output:

> Q:\Test\2019\08\29\SO_57717256.cmd
aPath = C:\just\a\long\path\to\a\file\in\the\file\system
aDir  = file
result= C:\just\a\long\path\to\a\file
aPath[1] = just
aPath[2] = a
aPath[3] = long
aPath[4] = path
aPath[5] = to
aPath[6] = a
aPath[7] = file <<< matches aDir file
aPath[8] = in
aPath[9] = the
aPath[10] = file <<< matches aDir file
aPath[11] = system
0

Here is a little approach using a recursive sub-routine, just for fun:

@echo off
set "aPath=C:\just\a\long\path\to\a\file\in\the\file\system"
set "aDir=file"
set "result=" & set "found="

call :RECURSIVE "%aPath%\."
if defined found echo/%result%
exit /B

:RECURSIVE
    if "%~nx1" == "" set "result=%~dp1" & exit /B
    call :RECURSIVE "%~dp1."
    if defined found (exit /B) else set "result=%result%%~nx1\"
    if /I "%~nx1" == "%aDir%" set "found=#" & set "result=%result:~,-1%"

This makes use of the ~ modifiers of command line or sub-routine arguments (parameters), which allow to split a path into pieces.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
0

A simpler approach:

@echo off
setlocal EnableDelayedExpansion

set aPath=C:\just\a\long\path\to\a\file\in\the\file\system\filenot\file\folder
set aDir=file
echo    %aPath%

rem This FOR is just for testing; remove it...
for /L %%n in (1,1,3) do (
   set "n=%%n"
   set "result="
   for %%a in ("!aPath:\%aDir%\=" "!") do if !n! gtr 0 set "result=!result!%%~a\%aDir%\" & set /A n-=1
   echo %%n: !result:~0,-1!
)

Output example:

   C:\just\a\long\path\to\a\file\in\the\file\system\filenot\file\folder
1: C:\just\a\long\path\to\a\file
2: C:\just\a\long\path\to\a\file\in\the\file
3: C:\just\a\long\path\to\a\file\in\the\file\system\filenot\file

EDIT: An even simpler method with the aid of some magic:

@echo off
setlocal EnableDelayedExpansion

set aPath=C:\just\a\long\path\to\a\file\in\the\file\system\filenot\file\folder
set aDir=file
echo    %aPath%

set n=%1
set "result="
set "p=%aPath:\=" & (if !n! gtr 0 set "result=!result!\!p!") & (if "!p!" equ "!aDir!" set /A n-=1) & set "p=%"
echo %1: %result:~1%

Output example:

C:\Tests> test 1
   C:\just\a\long\path\to\a\file\in\the\file\system\filenot\file\folder
1: C:\just\a\long\path\to\a\file

C:\Tests> test 2
   C:\just\a\long\path\to\a\file\in\the\file\system\filenot\file\folder
2: C:\just\a\long\path\to\a\file\in\the\file
Aacini
  • 65,180
  • 12
  • 72
  • 108