Внутреннее задержанное расширение в пакетном скрипте (windows)

Мне нужно сделать отложенное расширение внутри отложенного расширения, то есть что-то вроде:

!PARAMS[!BEFORE_LAST!]!

Конечно, вышеприведенное недействительно, поэтому я попытался обойти его с помощью цикла for, но безуспешно:

SETLOCAL EnableExtensions EnableDelayedExpansion

SET PARAM_COUNT=0
FOR %%P IN (%*) DO (
    SET /A PARAM_COUNT+=1
    SET PARAMS[!PARAM_COUNT!]=%%P

    IF !PARAM_COUNT! GTR 1 (
        SET /A BEFORE_LAST = !PARAM_COUNT!-1
        FOR /L %%G IN (!BEFORE_LAST!) DO SET BEFORE_LAST_PARAM=!PARAMS[%%G]!
        IF "!BEFORE_LAST_PARAM!"=="--buildroot" (
            REM perfrom some actions here
        )
    )
)
ENDLOCAL

Как я мог добиться объясненного поведения?

2 ответа

Решение

delayed expansion внутри delayed expansion не работает, попробуйте это:

CALL SET "myvar=%%PARAMS[!BEFORE_LAST!]%%"

Это не столько ответ, но, используя ответ @Enduro, я решил свою проблему. Я просто привожу здесь пример, чтобы увидеть, как его использовать.

Этот ответ был единственным, который у меня сработал! После МНОГО поисков; В основном я пытался создать файл со всеми именами пакетов приложений Android без кодов версий. Мы также использовали скрипт gradle для генерации имен в определенном формате, например: com.package.appname-releaseVersion.apk.

Вот исходный код для создания файла (apps.ls) с требуемыми именами пакетов, который я в основном использую вот так, внутри оболочки Android: for app in $(cat < apps.ls ); do monkey -p $app 1; done;. Он просто запускает все эти приложения, чтобы убедиться, что их службы запущены и зарегистрированы.

Мой оригинальный сценарий

      @echo off
setlocal EnableDelayedExpansion
cd "C:\remoteUpdate"

>apps.ls (
    for /r %%v in (*.apk) do (
        set "name=%%~nv"
        call :indexof "!name!" "-" idx
        call echo %%name:~0,!!idx!!%%
    )
)

C:\dos2unix\bin\dos2unix.exe apps.ls

@echo Done generating apps.ls


:indexof [%1 - string ; %2 - find index of ; %3 - if defined will store the result in variable with same name]
::http://ss64.org/viewtopic.php?id=1687
@echo off
setlocal enableDelayedExpansion

set "str=%~1"
set "s=!str:%~2=&rem.!"
set s=#%s%
if "%s%" equ "#%~1" endlocal& if "%~3" neq "" (set %~3=-1&exit /b 0) else (echo -1&exit /b 0) 

  set "len=0"
  for %%A in (2187 729 243 81 27 9 3 1) do (
    set /A mod=2*%%A
    for %%Z in (!mod!) do (
        if "!s:~%%Z,1!" neq "" (
            set /a "len+=%%Z"
            set "s=!s:~%%Z!"
            
        ) else (
            if "!s:~%%A,1!" neq "" (
                set /a "len+=%%A"
                set "s=!s:~%%A!"
            )
        )
    )
  )
  endlocal & if "%~3" neq "" (set %~3=%len%)
exit /b 0

Теперь проблема заключалась в том, что мне нужно было отфильтровать определенные пакеты из моего apps.ls файл,

Изменения

Все, что мне нужно было сделать, это изменить код внутри цикла for следующим образом:

          CALL SET "truncname=%%name:~0,!!idx!!%%"
    if NOT "!truncname!"=="com.blhealthcare.package1" if NOT "!truncname!"=="com.android.package2" echo !truncname!

Все, что я пробовал до этого, используя только набор, не работало. Однако использование call с set работало очень хорошо. Я также не могу найти никакой документации по этому поводу, так как по этой проблеме сложно даже искать. Я заметил, что call echo %%name:~0,!!idx!!%% печатал правильно, тогда как echo %%name:~0,!!idx!!%% печатал что-то вроде name:~0,28и не работает. Тогда я не мог этого понять, но сегодня я могу понять из ответа @ Endoro, что

внутри delayed expansion не работает

Другие вопросы по тегам