【问题标题】:Multiple conditions in For loop batch?For循环批处理中的多个条件?
【发布时间】:2012-06-27 16:16:53
【问题描述】:

我想在批处理文件中使用 for 循环交替打印 2 个单独的 txt 文件的每一行,我尝试使用 AND 但在运行时在 cmd.exe 中给出:“此时 AND 是意外的”我的批次。有什么想法吗?

 FOR /F "tokens=*" %%F in (!logPath!) AND for /f "tokens=*" %%H in (%%refLogPath) DO ( 

  REM print each line of log file and refLog file sequentially 
  echo %%F
  echo %%H
  REM set logLine=%%F
  REM check 'each line' of log file against ENG-REF.log

 )

【问题讨论】:

    标签: batch-file for-loop line cmd


    【解决方案1】:

    没有像AND 这样的关键字,通常你不能用两个 FOR 循环来解决这个问题。
    但是还有另一种方法可以使用set /p 读取文件。

    setlocal EnableDelayedExpansion
    <file2.txt (
      FOR /F "delims=" %%A in (file1.txt) DO (
        set /p lineFromFile2=
        echo file1=%%A, file2=!lineFromFile2!
      )
    )
    

    【讨论】:

    • 文件中的空行和/或不同的行数将导致当前编写的问题。 OP 还需要注意,SET /P 正在读取的文件中的任何行都不能超过 1021 字节。
    • 你能解释一下 set /p lineFromFile2= 应该完成什么吗?我在“=”符号的右侧看不到 promptString。 @dbenham 您如何建议可以解决此问题?
    • set /p 行从标准输入读取一行并将值分配给一个变量。由于标准输入已被重定向到您的文件,它会从文件中读取一行。不需要提示。至于“修复”代码,这取决于要求是什么。一行的长度可以超过 1021 个字符(字节)吗?任何一个文件中的一行都可以为空吗?如果两个文件都可以超过 1021 char set /p 长度限制,并且都可以有空行,那么任何批处理解决方案都会很慢。
    • @jerryh91 - 此解决方案还有其他限制。我发布了一个更强大但更慢的替代方案。在那里,我详细比较了这两种技术的局限性。我在我的解决方案中使用的一些技术可以在这个解决方案中使用,以消除这里的一些限制。
    【解决方案2】:

    我相信这与批处理解决方案一样强大。

    • 它处理两个文件中的空行
    • 每行最多可以读取大约 8k 字节
    • 文件中的行数不必匹配
    • 一行可以以任何字符开头(避免 FOR /F EOL 问题)
    • 一行可以包含! 而不会损坏(避免扩展 FOR 启用延迟扩展时变量)
    • 行可以是 Unix 或 Windows 样式。
    • 控制字符不会从行尾删除

    但是这个解决方案在读取一个大文件时会变得越来越慢,因为它必须从头开始重新扫描第二个文件的每一行。

    @echo off
    setlocal disableDelayedExpansion
    set "file1=file1.txt"
    set "file2=file2.txt"
    for /f %%N in ('find /c /v "" ^<"%file2%"') do set file2Cnt=%%N
    findstr /n "^" "%file1%" >"%file1%.tmp"
    findstr /n "^" "%file2%" >"%file2%.tmp"
    set "skip=0"
    set "skipStr="
    for /f "usebackq delims=" %%A in ("%file1%.tmp") do (
      set "ln1=%%A"
      call :readFile2
      set /a "skip+=1"
    )
    if %file2Cnt% gtr %skip% (
      for /f "usebackq skip=%skip% delims=" %%B in ("%file2%.tmp") do (
        set "ln2=%%B"
        setlocal enableDelayedExpansion
        set "ln2=!ln2:*:=!"
        (echo()
        (echo(!ln2!)
      )
    )
    del "%file1%.tmp" 2>nul
    del "%file2%.tmp" 2>nul
    exit /b
    
    :readFile2
    if %skip% gtr 0 set "skipStr=skip=%skip% "
    if %file2Cnt% gtr %skip% (
      for /f "usebackq %skipStr%delims=" %%B in ("%file2%.tmp") do (
        set "ln2=%%B"
        goto :break
      )
    ) else set "ln2="
    :break
    setlocal enableDelayedExpansion
    set "ln1=!ln1:*:=!"
    if defined ln2 set "ln2=!ln2:*:=!"
    (echo(!ln1!)
    (echo(!ln2!)
    exit /b
    

    如果该解决方案的限制与您的文件无关,则最好使用jeb's approach。它目前具有以下限制,只需稍作修改即可消除:

    • 文件的行数必须相同
    • 文件不能有空行
    • 文件 1 不得包含 ! 字符
    • File1 中的任何行都不能以; 开头

    此外,它在读取 File2 时具有以下限制,这些限制是 SET /P 限制所固有的

    • 行必须是 Windows 风格,以回车换行结束
    • 行不能超过 1021 个字符(字节),不包括行终止符
    • 控制字符将从每行的末尾删除

    更好的解决方案是使用批处理以外的方法。有很多可能性:VBS、JScript、PowerShell、perl……不胜枚举。

    【讨论】:

      猜你喜欢
      • 2013-10-07
      • 2023-04-08
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-09
      相关资源
      最近更新 更多