Пакетная команда поиска с переменной - PullRequest
0 голосов
/ 31 мая 2018

У меня есть список строковых элементов.

setlocal enabledelayedexpansion

CALL SET ListOFElts[0]=First
CALL SET ListOFElts[1]=Second
CALL SET ListOFElts[2]=Third

for /l %%n in (0,1,3) do (

   CALL SET Element=%%ListOFElts[%%n]%%

   whoami /groups /fo list | find "%Element%"
)

Я хочу попытаться найти каждый элемент с помощью команды find, но переменная Element, похоже, не "распознана",Когда я пытаюсь это сделать, он ничего не выводит для переменной Element:

setlocal enabledelayedexpansion

CALL SET ListOFElts[0]=First
CALL SET ListOFElts[1]=Second
CALL SET ListOFElts[2]=Third

for /l %%n in (0,1,3) do (

   CALL SET Element=%%ListOFElts[%%n]%%

   whoami /groups /fo list | find ""
)

-

Я также пробовал:

whoami /groups /fo list | find "%%Element%%"

Вывод предыдущей строки:

whoami /groups /fo list | find "%Element%"

-

Затем я попытался (с использованием setlocal enabledelayedexpansion):

whoami /groups /fo list | find "!Element!"

Вывод предыдущей строки:

whoami /groups /fo list | find "!Element!"

-

Я хочу получить это (например, первый цикл):

whoami /groups /fo list | find "First"

Спасибо за вашу помощь.

Ответы [ 3 ]

0 голосов
/ 31 мая 2018

Сначала откройте окно командной строки, запустите set /? и прочитайте всю справочную информацию по команде SET на нескольких страницах.Это объясняет использование отложенное расширение на IF и FOR примере.

Скорее всего, было бы также полезно прочитать ответыon:
Как интерпретатор сценариев Windows Command Interpreter (CMD.EXE) анализирует?

Ваш пакетный файл содержит setlocal enabledelayedexpansion вверху, чтобы включить отложенное расширение переменной среды.Но ни на одну переменную среды не ссылаются с синтаксисом !VariableName!, чтобы действительно использовать отложенное расширение переменной среды.По этой причине "%Element%" модифицируется командным процессором Windows уже при разборе всего блока команд, начиная с ( и заканчивая сопоставлением ) с "" перед выполнением команды FOR .Переменная окружения Element не определена до достижения командной строки FOR и cmd.exe анализирует всю командную строку FOR с блоком команд, заканчивающимся на ) в конце пакетафайл перед выполнением FOR .

CALL в основном используется для вызова подпрограммы или другого пакетного файла из пакетного файла.Использование CALL в простой командной строке может использоваться для получения командной строки, дважды проанализированной командным процессором Windows, во избежание использования отложенного расширения.В первых трех строках SET абсолютно не обязательно использовать CALL , так как при повторном разборе командных строк SET ничего не меняется.

Первое решение - без использования отложенного расширения с помощью CALL для двойного анализа двух командных строк в блоке кода.

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "ListOFElts[0]=First"
set "ListOFElts[1]=Second"
set "ListOFElts[2]=Third"

for /L %%I in (0,1,2) do (
    call set "Element=%%ListOFElts[%%I]%%"
    call %SystemRoot%\System32\whoami.exe /groups /fo list | %SystemRoot%\System32\find.exe "%%Element%%"
)

endlocal

Определение переменной среды Element не обязательно в командеблок как его значение ссылается только один раз.Таким образом, более компактным и, следовательно, более быстрым выполнением будет:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "ListOFElts[0]=First"
set "ListOFElts[1]=Second"
set "ListOFElts[2]=Third"

for /L %%I in (0,1,2) do call %SystemRoot%\System32\whoami.exe /groups /fo list | %SystemRoot%\System32\find.exe "%%ListOFElts[%%I]%%"

endlocal

Больше нет командного блока для выполнения с помощью FOR на каждой итерации цикла, только одна командная строка.Но тем не менее необходимо использовать команду CALL и использовать %%ListOFElts[%%I]%%, поскольку вся командная строка FOR уже проанализирована для ссылок %VariableName% перед выполнением FOR первый раз.Таким образом, "%ListOFElts[%%I]%" будет заменено уже на "" до того, как FOR будет вообще выполнено.

Третье решение - использование действительно отложенного расширения.Решение является компактной версией с использованием отложенного расширения, которое аналогично примеру вывода FOR с помощью команды SET :

@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "ListOFElts[0]=First"
set "ListOFElts[1]=Second"
set "ListOFElts[2]=Third"

for /L %%I in (0,1,2) do %SystemRoot%\System32\whoami.exe /groups /fo list | %SystemRoot%\System32\find.exe "!ListOFElts[%%I]!"

endlocal

Команда FINDSTR позволяет указывать несколько строк поиска.

@%SystemRoot%\System32\whoami.exe /groups /fo list | %SystemRoot%\System32\findstr.exe /L /C:"First" /C:"Second" /C:"Third"

FINDSTR выводит все строки из входного потока, содержащего любую из трех буквенно-чувствительных к регистру интерпретируемых строк, указанных в /C:"...",Эта единственная командная строка в командном файле заменяет все четыре вышеуказанных командных файла.

Чтобы понять используемые команды и их работу, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все отображаемые страницы справки.для каждой команды очень тщательно.

  • call /?
  • echo /?
  • endlocal /?
  • find /?
  • findstr /?
  • for /?
  • set /?
  • setlocal /?
  • whoami /?

См.также ответьте на Почему нет строкового вывода с 'echo% var%' после использования 'set var = text' в командной строке? для подробного объяснения, почему на всех SET командных строках "variable=value" используется вместо variable=value в пакетных файлах выше.

0 голосов
/ 31 мая 2018

Если только для обучения / скрытых целей,
почему бы просто не использовать

for %%A in (First Second Third) Do whoami /groups /fo list | find "%%A"

или даже

whoami /groups /fo list | findstr "First Second Third"
0 голосов
/ 31 мая 2018

Моя лучшая догадка:

@Echo Off
Set "ListOfElts[0]=First"
Set "ListOfElts[1]=Second"
Set "ListOfElts[2]=Third"

For /F "Tokens=1* Delims==" %%A In ('Set ListOfElts[ 2^>Nul'
) Do WhoAmI /GROUPS /FO LIST | Find /I "%%~B"

Pause
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...