PetSerAl , как он часто делает, предоставил критический указатель в комментарии:
Цикл
cmd.exe
for /f
по умолчанию разбивает свои входные строки на токены по пробелам , так что for /f %%a in (...) do
ставит только на первое место такой токен в переменной %%a
.
Это поведение по умолчанию можно изменить с помощью строки параметров : for /f "<options>" %%a in (...) do
.
Запуск for /?
из приглашения cmd.exe
описывает его синтаксис:
eol=c - specifies an end of line comment character
(just one)
skip=n - specifies the number of lines to skip at the
beginning of the file.
delims=xxx - specifies a delimiter set. This replaces the
default delimiter set of space and tab.
tokens=x,y,m-n - specifies which tokens from each line are to
be passed to the for body for each iteration.
This will cause additional variable names to
be allocated. The m-n form is a range,
specifying the mth through the nth tokens. If
the last character in the tokens= string is an
asterisk, then an additional variable is
allocated and receives the remaining text on
the line after the last token parsed.
usebackq - specifies that the new semantics are in force,
where a back quoted string is executed as a
command and a single quoted string is a
literal string command and allows the use of
double quotes to quote file names in
file-set.
Если вы хотите, чтобы каждая строка ввода записывалась в переменную single , у вас есть две опции:
Примечание. В приведенных ниже примерах используется следующая командная строка PowerShell, которая просто выводит строковый литерал с несколькими начальными, внутренними и конечными пробелами one two
.
powershell -command " ' one two ' "
Чтобы упростить цитирование, ниже используется опция usebackq
, которая позволяет встраивать команду в `...`
.
Также обратите внимание, что хорошая практика - добавлять -NoProfile
в powershell.exe
командную строку , чтобы предотвратить ненужную - и потенциально изменяющую поведение - загрузку профиля пользователя; Я опущу это ниже для краткости.
"delims="
: сохранение строки в точности как есть
@echo off
for /f "usebackq delims=" %%a in (`powershell -command " ' one two ' "`) do echo Result is "%%a"
Вышеуказанные выходы:
Result is " one two "
Обратите внимание, как также сохранялись начальные и конечные пробелы.
Важно : чтобы delims=
был признан деактивирующим синтаксическим анализом на основе разделителя (на основе разделителя), его необходимо поместить в самом конце строки параметров.
"tokens=*"
: обрезка ведущий пробел
@echo off
for /f "usebackq tokens=*" %%a in (`powershell -command " ' one two ' "`) do echo Result is "%%a"
Вышеуказанные выходы:
Result is "one two "
Обратите внимание, как ведущие пробелы были обрезаны .
Любопытно, что обрезка применяется только к начальным пробелам, и, похоже, также нет прямого способа обрезать концевые пробелы.