在批处理文件中使用变量作为标志

时间:2011-08-17 20:47:40

标签: batch-file dos

我正在编写一个批处理文件,该文件解析文本文件并仅在读取所述文件中的特定行时生成输出。请考虑以下名为 sample.txt 的文本文件:

List1
Dog
Cat
Monkey

List2
Horse
Bear
Dog
Pig
Dog

假设我的批处理文件的目标是输出每个列表中单词“Dog”出现的次数。所以在 sample.txt 中有两个列表:一个有1个“Dog”实例,另一个有2个。为了在批处理文件中实现这个,我写了以下内容:

@echo off
set count=0
set first_iteration=1

for /f "tokens=*" %%A in (sample.txt) do (
    echo %%A > tempfile.txt

    FINDSTR /R ".*List.*" tempfile.txt > NUL

    REM If true, this is a list header
    if errorlevel 1 (
        if %first_iteration% EQU 1 (
            REM PROBLEM HAPPENS HERE
            set first_iteration=0
        ) else (
            echo %count% >> log.txt
            set count=0 
        )
    REM An animal has been found
    ) else (
        FINDSTR /R ".Dog.*" tempfile.txt > NUL
        if NOT errorlevel 1  (
            set \A count+=1
        )
    )
)
del tempfile.txt
echo %count% >> log.txt
pause

所以基本上这段代码的工作方式是我必须打印出在读取新列表标题(List1和List2)时找到了多少“Dogs”。第一次发生这种情况时,计数将为零,因为它也是 sample.txt 文件的第一行。例如,在读取List1之后,它会一直读取,直到找到List2,计数为1.然后计数重置为0,因为它正在读取新列表。当批处理文件读取第二个列表时,因为它也是最终列表,所以它需要输出它具有的任何计数。

* first_iteration *变量跟踪批处理文件是否正在读取第一个列表,以便它知道何时不输出 count 。但问题是,* first_iteration *的值不会改变,因为Batch在单行命令中如何解释变量值(如果仔细查看所有if / else语句是否包含在一组括号中)。

那么有没有办法以批处理文件的形式实现我的目标?

2 个答案:

答案 0 :(得分:2)

  

假设我的批处理文件的目标是输出多少   每次列表中都会显示“狗”字样。

SET counter=0
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "USEBACKQ tokens=*" %%F IN (`TYPE "C:\Folder\sample.txt" ^| FIND /I "dog"`) DO (
  SET /a counter=!counter!+1
)
ECHO Dog shows up !counter! many times in this file.

没有测试......不记得你是否应该使用!循环后调用计数器时的%或%...

答案 1 :(得分:1)

您可以使用!first_iteration!进行延迟评估。在使用SETLOCAL ENABLEDELAYEDEXPANSION启用它之后,您需要在脚本中的几个位置使用它。

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set count=0
set first_iteration=1

for /f "tokens=*" %%A in (sample.txt) do (
    echo %%A > tempfile.txt

    FINDSTR /R ".*List.*" tempfile.txt > NUL

    REM If true, this is a list header
    REM your post was missing the NOT here
    if NOT errorlevel 1 (
        if !first_iteration! EQU 1 (
            SET first_iteration=0
        ) else (
            echo !count! >> log.txt
            set count=0 
        )
    REM An animal has been found
    ) else (
        REM your post was missing the first * on this line
        FINDSTR /R ".*Dog.*" tempfile.txt > NUL
        if NOT errorlevel 1 (
            REM your post used a \ instead of a / here
            set /A count=1+!count!
        )
   )
)
del tempfile.txt
echo %count% >> log.txt