Использование подстроки в переменной в выражении FOR - PullRequest
0 голосов
/ 03 мая 2019

Каков правильный синтаксис для проверки символа 1 в каждой переменной в выражении FOR? Моя цель - определить переменные из командной строки, которые начинаются с тире в символе 1.

Вот пример командной строки: m

mysample.bat -p1=1 -p2=2 -p3="abc" myfile

Вот что я пробовал, используя синтаксис подстроки с %%~1:

setlocal enabledelayedexpansion
(for %%i in (%*) do if not %%~1:~0,1%=='-' set "filename=%%~i")>nul

Это дает следующее сообщение об ошибке:

"Недопустимо следующее использование оператора пути в подстановке пакетных параметров:% ~ i")> nul "

1 Ответ

0 голосов
/ 04 мая 2019

Давайте сначала посмотрим на mysample.bat, содержащий только

@echo off
for %%I in (%*) do echo %%I

и что выводится при запуске в окне командной строки в каталоге, содержащем mysample.bat командную строку:

mysample.bat -p1=1 -p2=2 -p3="abc" myfile

Вывод:

-p1
1
-p2
2
-p3
"abc"
myfile

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

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

set "FileName="
for %%I in (%*) do set "FileName=%%~I"
if defined FileName echo File name is: %FileName%

Вывод: File name is: myfile

Но как насчет вызова командного файла с:

mysample.bat -p1=1 myfile -p2=2 -p3="abc"

Что ж, неудивительно, что вывод неправильный с: File name is: abc

Как насчет использованиякоманда SHIFT ?

@echo off
set "ArgNumber=1"
:ArgLoop
if "%~1" == "" goto :EOF
echo Argument %ArgNumber% is: "%~1"
set /A ArgNumber+=1
shift
goto ArgLoop

Вывод при запуске пакетного файла с приведенным выше списком аргументов:

Argument 1 is: "-p1"
Argument 2 is: "1"
Argument 3 is: "myfile"
Argument 4 is: "-p2"
Argument 5 is: "2"
Argument 6 is: "-p3"
Argument 7 is: "abc"

Так что cmd.exe интерпретирует также равныеподписать в качестве разделителя аргументов =, не находясь внутри двойных кавычекстроковая строкаНу, FOR - это внутренняя команда cmd.exe, и поэтому тот же код используется для интерпретации списка аргументов пакетного файла, а также набора аргументов FOR .

Подстановка строк поддерживается только cmd.exe для переменных среды.Невозможно применить их к аргументам пакетного файла или к строкам, присвоенным FOR переменным цикла.

Так что давайте посмотрим на код пакетного файла, который действительно оценивает аргументы:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FileName="
rem Delete all environment variables of which name starts with Parameter.
for /F "delims==" %%I in ('set Parameter 2^>nul') do set "%%I="

:ArgLoop
set "Argument=%~1"
if defined Argument (
    if /I "%Argument:~0,2%" == "-p" (
        set "Parameter %Argument:~2%=%~2"
        shift
    ) else if not defined FileName (
        set "FileName=%~1"
    ) else (
        echo WARNING: Unknown argument: "%~1"
    )
    shift
    goto ArgLoop
)
rem The current argument could be "" which is an empty argument.
rem The current argument could be also just " on being last argument.
rem Don't break the argument loop on such an empty argument, but
rem instead just ignore this empty argument with a warning.
set Argument=%1
if defined Argument (
    echo WARNING: Empty argument: %Argument%
    shift
    goto ArgLoop
)

echo/
if defined FileName echo File name is: "%FileName%"
for /F "tokens=1* delims==" %%I in ('set Parameter 2^>nul') do echo %%I is: "%%~J"
endlocal

Давайте запустим этот командный файл из командной строки:

mysample.bat "" -p1="First Paramter" myfile -p2 "2nd parameter" What's that -p3,ThirdParameter -p4 Fourth value! "

Вывод:

WARNING: Empty argument: ""
WARNING: Unknown argument: "What's"
WARNING: Unknown argument: "that"
WARNING: Unknown argument: "value!"
WARNING: Empty argument: "

File name is: "myfile"
Parameter 1 is: "First Paramter"
Parameter 2 is: "2nd parameter"
Parameter 3 is: "ThirdParameter"
Parameter 4 is: "Fourth"

По моему мнению, этот вывод хорош.Он информирует пользователя о явно неверно указанных аргументах, но обрабатывает, тем не менее, действительные параметры.

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

  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?
  • shift /?

Прочтите также статью Microsoft о Использование операторов перенаправления команд для объяснения 2>nul.Оператор перенаправления > должен быть экранирован с помощью символа вставки ^ в командной строке FOR , чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , котораявыполняет встроенную командную строку set в отдельном командном процессе, запущенном в фоновом режиме.

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