В пакетном скрипте разделить только последнюю строку в переменной - PullRequest
0 голосов
/ 14 февраля 2019

В пакетном скрипте мне нужно разделить только последнее совпадение строк в переменной в цикле, пока у меня не останется совпадение строк.

Input=Level1/Level2/Level3/Level4/LevelN

(где N может быть любым числом)
Вывод:

Level1/LeveL2/Level3/Level4
Level1/LeveL2/Level3
Level1/Level2
Level1

Я пробовал обычные циклы "for /f "delims=/"", но они выводят только каждое разбиение входной переменной в отдельной строке.Кроме того, значение «N» может варьироваться.Поэтому я не могу установить количество токенов на определенное значение.

Пожалуйста, помогите.

Ответы [ 4 ]

0 голосов
/ 15 февраля 2019

Более классический подход, просто для удовольствия ...

@echo off
setlocal EnableDelayedExpansion

set "Input=Level1/Level2/Level3/Level4/LevelN"

rem Split the string, join it again and store partial results
set "aux="
set "n=0"
for %%a in ("%Input:/=" "%") do (
   set "aux=!aux!/%%~a"
   set /A n+=1
   set "out[!n!]=!aux:~1!"
)

rem Show results in reverse order
set /A n-=1
for /L %%i in (%n%,-1,1) do echo !out[%%i]!
0 голосов
/ 14 февраля 2019

Это легко сделать с помощью регулярного выражения в PowerShell.Поскольку регулярное выражение является жадным по умолчанию, оно получит все до последнего SOLIDUS и сохранит его в группе $ 1.

SET "S=Level1/Level2/Level3/Level4/LevelN"

FOR /F "delims=" %%a IN ('powershell -NoL -NoP "'%S%' -replace '(.*/).*', '$1'"') DO (
    SET "RESULT=%%a"
)

ECHO RESULT is set to %RESULT%

Редакция:

Это выводит все группы, а не толькопоследний.

SET "S=Level1/Level2/Level3/Level4/LevelN"

FOR /F "delims=" %%a IN ('powershell -NoL -NoP -Command ^
    "$a = '%S%'.Split('/'); " ^
    "for ($i = $a.Count - 2; $i -ge 0; $i--) { $a[0..$i] -join '/' }"') DO (
    ECHO %%a
)
0 голосов
/ 14 февраля 2019

Вот хороший рекурсивный подход, который использует модификаторы ~ , предполагая, что входная строка предоставляется в виде аргумента командной строки в кавычках (""), который не начинается с /, не содержит двух последовательных // и ни одного из символов ", \, *, ?, <, >:

@echo off
rem // Store argument in variable:
set "INPUT=%~1"
if not defined INPUT exit /B
rem /* Precede with `\` and replace each `/` by `\`, so the resulting string appears to
rem    be an absolute path, which can be split by `~` modifiers of `for` variables;
rem    the inner `for` loop resolves the split path and removes any `\.` suffix: */
for %%I in ("\%INPUT:/=\%") do for %%J in ("%%~pI.") do set "REST=%%~pnxJ"
rem // Revert replacement of every `/` by `\` and remove the previously preceded `\`:
set "REST=%REST:\=/%"
set "REST=%REST:*/=%"
rem // If there is a string left, output it and call this script recursively:
if defined REST (
    setlocal EnableDelayedExpansion
    echo(!REST!
    endlocal
    call "%~f0" "%REST%"
)
0 голосов
/ 14 февраля 2019

Этот сайт не работает таким образом.Вы должны опубликовать некоторый код и объяснить, какие у вас проблемы с ним.Таким образом, вы можете понять изменения, внесенные в ваш собственный код.Если вы запросите у нас код любой код , то вы можете получить его ("любой код"), например:

@echo off
setlocal EnableDelayedExpansion

set "Input=Level1/Level2/Level3/Level4/LevelN"

:loop
   set "Output="
   set "part=%Input:/=" & set "Output=!Output!/!part!" & set "part=%"
   set "Input=%Output:~1%"
   if "%Input%" equ "~1" goto exitLoop
   echo "%Input%"
goto loop

:exitLoop
...