Как выполнить код в большинстве каталогов, кроме перечисленных в файле с командным файлом? - PullRequest
3 голосов
/ 09 февраля 2012

Таким образом, я пытаюсь выполнить код для большинства каталогов под другим, кроме тех, которые я перечисляю в текстовом файле.Так, например, если бы я хотел запустить код для всех каталогов непосредственно в C: \, но не сказать C: \ avomeme \, я бы добавил C: \ avome в качестве строки в exclusion.txt.Но приведенный ниже код, похоже, не работает.Любые идеи о том, как это можно сделать?

for /f %%d in ('dir /b C:\') do (
 find /c "C:\%%d" exclusions.txt 
 if %errorlevel% equ 1 (
  Do code here

)

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012
@echo off
for /D %%d in (*) do (
    %WINDIR%\system32\find "%%d" exclude.list >nul
    if errorlevel 1 (
        echo good %%d
    ) else (
        echo bad %%d
    )
)
1 голос
/ 09 февраля 2012

Причина, по которой ваш код не работает, заключается в том, что весь текст предложения FOR DO () анализируется сразу перед фактическим выполнением оператора FOR. Но значение% ERRORLEVEL% расширяется во время разбора, поэтому вы никогда не увидите обновленное значение во время выполнения.

У вас есть дополнительные проблемы

  • вы должны использовать опцию DIR / AD, чтобы ограничить список только каталогами

  • вам не интересно видеть вывод вашей команды FIND, поэтому вы, вероятно, должны перенаправить вывод в nul

далndkoa есть одно решение, которое будет работать.

Другая альтернатива - использовать отложенное расширение

setlocal enableDelayedExpansion
for /f %%d in ('dir /ad /b C:\') do (
  find /c "C:\%%d" exclusions.txt >nul
  if !errorlevel! equ 1 (
    REM Do code here
  )
)

Существует риск того, что %% d повредит значение во время расширения, если оно содержит !. Эту проблему можно решить, переключив задержанное расширение в цикле.

Другой альтернативой является использование оператора ||, что означает выполнение следующей команды в случае сбоя предыдущей команды.

for /f %%d in ('dir /ad /b C:\') do (
  find /c "C:\%%d" exclusions.txt >nul || (
    REM Do code here
  )
)

Возможно, лучший вариант - вообще избавиться от необходимости беспокоиться об уровне ошибок, передав результаты DIR напрямую в FINDSTR с помощью параметров / V и / G: для фильтрации значений, которые появляются в вашем списке исключений.

Следующее должно работать

for /f %%d in ('dir /ad /b C:\ ^| findstr /l /v /g:"exclude.list"') do (
  REM - Do code here
)

НО - есть неприятная ошибка FINDSTR, которая может привести к сбою, если вы ищете несколько литеральных строк разной длины.

Исправление состоит в том, чтобы заставить FINDSTR вместо этого использовать регулярные выражения, но тогда вам нужно избегать любых метасимволов регулярного выражения, которые могут появиться в вашем списке исключений. Например, каталог с именем myName.ext должен быть экранирован как myName\.ext.

for /f %%d in ('dir /ad /b C:\ ^| findstr /r /v /g:"exclude.list"') do (
  REM - Do code here
)

Другие символы, которые должны быть экранированы в списке exclusion.list: \, ^, $, [, ]

...