2010-12-02 3 views
16

Следующей вложенную для контура сводит меня с умом (на Windows 7):Уплотненной партии для петель

@echo off 
SetLocal EnableDelayedExpansion 

set TESTDIRS=fast mid slow 
set TD=src\test\resources\testsuite 

for %%d in (%TESTDIRS%) do (
    set CTD=%TD%\%%d 
    echo CTD: !CTD! 
     REM Echos the expected path 
    echo CTD: %CTD% 
     REM Echos nothing -- understandable 

    for /R !CTD! %%f in (*.fs) do (echo %%f) 
     REM Echos nothing -- why? 
    for /R src\test\resources\testsuite\fast %%f in (*.fs) do (echo %%f) 
     REM Echos expected files 
) 

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

ответ

8

Что делать, если вы использовали pushd !CTD! и popd, и разрешили ли FOR /R использовать текущий каталог?

+2

+1 для хорошего и простого решения проблемы – jeb 2010-12-02 19:46:39

+0

Это действительно хороший обходной путь! Но, вероятно, не всегда применимо ... – 2010-12-03 09:34:25

4

Это не очевидно! Это специальный синтаксический разбор ДЛЯ!
A Для команды команда анализируется непосредственно после этапа escape/special character (для обнаружения скобок), но в результате вы не можете использовать отложенное или %% var расширение в качестве параметров.

FOR %%a in (%%%%B) do (
    FOR %%a in (1) DO (<<< this %%a will not replaced with %%B 
     echo %%a - shows 1, because %%a is the name of the inner variable 
     echo %%B - doesn't work 
) 
) 

А также это не может работать:

set chars=abc 
FOR /F "delims=!chars!" %%N in (bla) DO .... 

не установлен , б и с в delims, но !, с, ч, и г вместо этого.

EDIT: В скобках замедленное расширение делает работу, как ожидается, однако:

set var=C:\temp 
For %%a in (!var!) DO echo %%a 

Я бы ожидать, что вы должны использовать функцию, чтобы решить вашу проблему.

+1

Извините, но я не вижу, как ваш ответ помогает мне с моим вопросом, поскольку он только говорит мне, что не работает. Кроме того, я уже упоминал в своем вопросе, что я знаю о возможности замены внутреннего цикла на подпрограмму, но мой вопрос заключался в том, как сделать работу вложенного цикла. – 2010-12-08 08:16:42

+1

Извините, но я полагаю, что вы можете использовать только PUSHD-решение от Ben Voigt.С расширением это кажется невозможным, потому что путь для внутреннего цикла расширяется только один, в начале первой круглой скобки, – jeb 2010-12-08 09:13:28

18

Просто чтобы дать пример вложенного цикла, который работает:

@echo off 
SetLocal 

set B=alpha beta gamma 
set A=eins zwo 

FOR %%b in (%B%) do (
    FOR %%a in (%A% %%b) DO (
    echo %%b -^> %%a 
) 
) 

Выход (по крайней мере, на Windows 7) является

alpha -> eins 
alpha -> zwo 
alpha -> alpha 
beta -> eins 
beta -> zwo 
beta -> beta 
gamma -> eins 
gamma -> zwo 
gamma -> gamma 

Это поддерживает наблюдение Джеба, что переменная расширение петель работ если они встречаются внутри скобок (даже без задержки расширения).

8

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

@echo off 

set TESTDIRS=fast mid slow 
set TD=src\test\resources\testsuite 

for %%d in (%TESTDIRS%) do call :process_testdir %%d 
goto :eof 

:process_testdir 
set CTD=%TD%\%1 
echo CTD: %CTD% 
    REM Echos the expected path 

for /R %CTD% %%f in (*.fs) do (echo %%f) 
    REM Echos as expected 

goto :eof 

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

Смежные вопросы