Отображение строк из текстового файла в пакетном файле - PullRequest
0 голосов
/ 24 февраля 2010

Файл test.cmd:

name=dummy  

for /f "eol=; tokens=1 delims=," %%i in (list.txt) do (  
echo i: %%i  
set name=%%i  
echo name: %name%)  

файл list.txt содержит следующие строки (по одному имени в строке):

John  
Tom  
Erica  
Sara  

Каждый раз, когда я запускаю этот пакет, я получаю этот вывод:

i: John  
name: dummy  
i:T om  
name: dummy  
i: Erica  
name: dummy  
i: Sara  
name: dummy  

Кажется, что имени переменной не присваивается значение %%i

Есть идеи?

1 Ответ

1 голос
/ 24 февраля 2010

Вы попали в старую ловушку неиспользования отложенного расширения.

Для быстрого исправления просто поставьте

setlocal enabledelayedexpansion

перед этим циклом в вашем пакетном файле и используйте !name! вместо %name%.

CMD расширяет переменные при разборе команды. Команда в этом смысле представляет собой одну строку или «блок», разделенные скобками. Полный цикл for анализируется только один раз, и на этом этапе %name% заменяется значением, которое он имеет в этой точке, а именно "dummy". Затянувшееся расширение, с другой стороны, использует ! вместо % для разграничения имен переменных, а затем переменные раскрываются непосредственно перед выполнением команды.

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

Задержка расширения переменной среды полезно для обхода ограничения текущего расширения что происходит, когда строка текста читать, а не когда это выполняется. Следующий пример демонстрирует проблема с непосредственной переменной расширение:

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "%VAR%" == "after" @echo If you see this, it worked
)

никогда не будет отображать сообщение, так как %VAR% in оба IF операторы подставляется при первом IF утверждение читается, так как оно логично включает в себя тело IF, которое является сложное утверждение. Так что IF внутри составного оператора действительно сравнивая «до» с «после» который никогда не будет равным. Так же, следующий пример не будет работать как Ожидаемый результат:

set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%

в том смысле, что не создает список файлы в текущем каталоге, но вместо этого просто установите LIST переменная до последнего найденного файла. Опять же, это потому, что %LIST% расширен только один раз, когда FOR заявление читается, и в то время переменная LIST пуста. Итак фактический FOR цикл, который мы выполняем:

for %i in (*) do set LIST= %i

, который просто устанавливает LIST на последний найденный файл.

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

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" @echo If you see this, it worked
)

set LIST=
for %i in (*) do set LIST=!LIST! %i
echo %LIST%
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...