批处理 - for循环内部循环

时间:2014-04-26 20:41:08

标签: batch-file for-loop

是否可以在另一个for循环中使用for循环?

我有两个文件,第一个文件包含

...
"bla","bli","blu",XX
"bla","bli","blu",YY
...

第二个包含:

...
XX,some string
XX,some string
YY,diferent string
YY,diferent string
...

我想要做的是写一个文件行,如:

...
"bla","bli","blu",some string
"bla","bli","blu",diferent string
...

我最好的尝试是没有工作

for /f "tokens=1-10 delims=," %%1 in (semi-final.txt) do (
    :: echo "bla","bli","blu"
echo %%1,%%2,%%3,%%4,%%5,%%6, | tr -d "\r\n" >> final.txt

    :: set var=XX  or set var=YY
set var=%%7

for /f "tokens=1,2 delims=," %%1 in (codes.txt) do (
            :: Find XX in codes.txt for exchange
    if /i "%%2"=="!var!" echo %%1, | tr -d "\r\n" >> final.txt
)

    ::Other echo after that XX , isn't important
echo %%7,%%8,%%9,%%10 >> final.txt
)

编辑:

我有SHIFT问题:/在下面的代码中注释

@echo off
setlocal EnableDelayedExpansion

for /f "tokens=1-11 delims=, skip=1" %%1 in (semi-final.txt) do (
    echo %%1,%%2,%%3,%%4,%%5,%%6, >> final.txt

    set var=%%7
    set b=!var:~2,2!

        call :inner !b!

        shift
        shift
        shift
        :: Still %%6 is the same asi in first command

    echo %%6,%%7,%%8,%%9 >> final.txt
)
goto :eof

:inner
for /f "tokens=1,2 delims=," %%X in (codes.txt) do (
    IF /i "%%Y"=="!b!" ( 
        echo '%%X', >> final.txt
            goto :next
    )
)
echo '', >> final.txt
:next
goto :eof

2 个答案:

答案 0 :(得分:1)

你还有很多问题。

  • FOR变量名是单个字符,使用多个令牌时的顺序是ASCII顺序。因此%%9之后的变量是%%:。不可能有一个名为%%10的FOR变量。

  • SHIFT命令仅对批处理参数进行操作,而不对FOR变量进行操作。即使您选择使用数字作为FOR变量,但这并不意味着您可以将它们移位。

  • 不需要SHIFT FOR变量,只需使用字母字符就可以轻松找出要使用的变量。然后在一个循环中处理多达26个FOR变量变得很简单。此外,您可以指定所需的标记:FOR /F "tokens=1-7,9-11 delims=," %%A将%% A - %% G分配给标记1-7,将%% H - %% J分配给标记9-11。

可以做出重大改进。

  • 没有理由使用TR的多个ECHO来打印单行。只需延迟打印任何信息,直到您拥有整行。

  • 您可以使用FINDSTR快速找到匹配的行,并使用另一个FOR / F来解析所需的值。这比用FOR / F读取整个第二个文件要快得多。

  • 在循环中使用追加模式效率低下 - 重定向打开文件并定位指针需要时间。将整个循环包含在另一组括号中并仅重定向一次要快得多。

  • 不需要CALLed子程序。一切都可以在主循环中完成。

尝试一下:

@echo off
(
  for /f "tokens=1-7,9-11" %%A in (semi-final.txt) do (
    for /f "tokens=2" %%X in ('findstr /bl "%%G," codes.txt') do (
      echo %%A,%%B,%%C,%%D,%%E,%%F,%%X,%%H,%%I,%%J
    )
  )
)>final.txt

如果code.txt可能有多行具有相同的代码,并且您只需要第一个找到的行的值,那么您将需要一个子例程。通常,除了在循环的直接范围内,您不能访问FOR变量。因此,您不希望能够在循环中调用子例程并仍然在子例程中引用循环变量。但是有一个鲜为人知的特性,如果你在另一个FOR变量的范围内,那么仍然可以访问仍然活动循环的所有FOR变量。

@echo off
(for /f "tokens=1-7,9-11" %%A in (semi-final.txt) do call :lookup "%%G")>final.txt

:lookup
for /f "tokens=2" %%X in ('findstr /bl "%~1," codes.txt') do (
  echo %%A,%%B,%%C,%%D,%%E,%%F,%%X,%%H,%%I,%%J
  exit /b
)

答案 1 :(得分:0)

您对两个循环使用相同的FOR变量(%%1)。由于它们是嵌套的,因此您应该使用不同的变量。第一个for循环声明10个变量(因为你要求10个令牌),所以对于第二个变量,你需要不同的变量。尝试在第二个循环中使用%%X(使用%%X%%Y代替%%1%%2)。