Использование переменных в качестве флагов в пакетных файлах - PullRequest
2 голосов
/ 18 августа 2011

Я пишу пакетный файл, который анализирует текстовый файл и выдает результат только тогда, когда он читает определенную строку в указанном файле. Рассмотрим следующий текстовый файл с именем sample.txt :

List1
Dog
Cat
Monkey

List2
Horse
Bear
Dog
Pig
Dog

Допустим, цель моего Batch-файла - вывести, сколько раз слово «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). В первый раз, когда это произойдет, счетчик будет равен нулю, потому что это также первая строка файла sample.txt . Например, после считывания List1 он продолжает чтение до тех пор, пока не найдет List2, в котором счетчик равен 1. Затем счетчик сбрасывается в 0, поскольку он читает новый список. К тому времени, когда пакетный файл читает второй список, так как он также является окончательным списком, он должен вывести любое количество, которое у него есть.

Переменная * first_iteration * отслеживает, читает ли пакетный файл первый список, чтобы знать, когда не следует выводить count . Но проблема в том, что значение * first_iteration * не изменяется из-за того, как Batch интерпретирует значения переменных в однострочной команде (если вы внимательно посмотрите, все ли операторы / else заключены в один набор скобок).

Так есть ли способ реализовать мою цель в виде пакетного файла?

Ответы [ 2 ]

2 голосов
/ 18 августа 2011

Допустим, цель моего Batch-файла - вывести, сколько раз слово "Dog" появляется в каждом списке.

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 голос
/ 18 августа 2011

Вы можете использовать !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
...