проверить состояние «IF» внутри цикла FOR (партия / cmd) - PullRequest
4 голосов
/ 22 июля 2009

Код, который мне нужно реализовать в командном файле Windows, выглядит следующим образом (в настоящее время он находится в Perl):

while(<file>)
{
   if($_ =~ m/xxxx/)
   {
      print OUT "xxxx is found";
   }
   elsif($_ =~ m/yyyy/)
   {
      next;
   }
   else
   {
      ($a,$b) = split(/:/,$_);
      $array1[$count] = $a;
      $array2[$count] = $b;
      $count++;
   }
}

Мои вопросы:

  1. Возможен ли такой уровень сложности в пакетных файлах Windows?
  2. Если так, как я могу поставить условие If внутри цикла для чтения текста файл

Спасибо за ваше внимание. Если вы знаете ответы или у вас есть идеи / подсказки о том, как найти ответ, поделитесь ими.

РЕДАКТИРОВАТЬ: я работаю в Windows. Я могу использовать только то, что предоставляется Windows по умолчанию, а это значит, что я не могу использовать утилиты Unix.

Ответы [ 6 ]

9 голосов
/ 23 июля 2009

Ввести if в for в общем случае просто:

for ... do (
    if ... (
        ...
    ) else if ... (
        ...
    ) else (
        ...
    )
)

Цикл for, который перебирает строки, может быть записан с помощью ключа /f:

for /f "delims=" %%s in (*.txt) do (
    ...
)

Регулярные выражения предоставляются findstr. Он будет соответствовать stdin, если входной файл не указан. Вы можете перенаправить вывод в NUL, чтобы он не отображал найденную строку, и просто используйте ее errorlevel, чтобы увидеть, соответствует ли она или нет (0 означает совпадение, а не 0 означает, что нет). И вы можете разделить строку, используя /f снова. Итак:

set count=0
for /f "delims=" %%s in (foo.txt) do (
    echo %%s | findstr /r xxxx > NUL
    if errorlevel 1 (
        rem ~~~ Didn't match xxxx ~~~
        echo %%s | findstr /r yyyy > NUL
        if errorlevel 1 (
            rem ~~~ Didn't match yyy ~~~
            for /f "delims=; tokens=1,*" %%a in ('echo %%s') do (
                 set array1[!count!]=%%a
                 set array2[!count!]=%%b
                 set /a count+=1
            )
        )
    ) else (
        echo XXX is found
    )
)
2 голосов
/ 22 июля 2009

Я думаю, что это слишком много боли для CMD.EXE, и даже это невозможно, хотя я могу ошибаться в последнем.

Вам лучше использовать WSH (Windows Scripting Host), который позволяет использовать JScript или VbScript и присутствует практически во всех системах. (и вы можете предоставить распространяемый, если хотите)

1 голос
/ 23 июля 2009

У меня нет опыта работы с Perl, но если я правильно понимаю вашу команду, это будет так. Помните, что пакетные сценарии очень примитивны и не имеют хороших методов очистки, поэтому некоторые символы (в основном & | <>) разбивают это на части.

@ECHO OFF
SETLOCAL
SET COUNT=0
FOR /F "DELIMS=" %%A IN ('file') DO CALL :SCAN %%A
:SCAN
ECHO %*|FIND "xxxx">NUL
IF %ERRORLEVEL%==0 ECHO xxxx is found&GOTO :EOF
ECHO %*|FIND "yyyy">NUL
IF %ERRORLEVEL%==0 GOTO :EOF
FOR /F "TOKENS=1,2 DELIMS=:" %%A IN ('ECHO %*') DO SET ARRAY1[%COUNT%]=%%A&SET ARRAY2[%COUNT%]=%%B
SET /A COUNT+=1

Если вы используете FINDSTR вместо FIND, вы можете использовать регулярное выражение. Если вы хотите использовать значение ARRAY1 [% COUNT%] (с переменной внутри него), вам придется заменить «SETLOCAL» на «SETLOCAL ENABLEDELAYEDEXPANSION» и использовать! ARRAY1 [% COUNT%]!

PS: я не тестировал этот скрипт, но насколько я могу судить, он должен работать.

1 голос
/ 22 июля 2009

Вот примерный эквивалент вашего Perl-скрипта для VBScript.

Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = "c:\test\file.txt"
Set objFile = objFS.OpenTextFile(strFile)
Dim array1()
Dim array2()
count=0
Do Until objFile.AtEndOfStream
    strLine = objFile.ReadLine
    If InStr(strLine,"xxxx") >0 Then
        WScript.Echo " xxxx is found."
    Else
        s = Split(strLine,":")
        ReDim Preserve array1(count)
        ReDim Preserve array2(count)
        array1(count)=s(0)
        array2(count)=s(1)
        count=count+1
    End If 
Loop
'print out the array elements
For i=LBound(array1) To UBound(array2)
    WScript.Echo array1(i)
    WScript.Echo array2(i)
Next

Для вашей информации, всегда есть Perl для окон, который вы можете использовать без необходимости изучать другой язык.

0 голосов
/ 03 августа 2016

Это возможно!

FOR ................. DO  (
    (YOUR_CONDITION && echo "YES" ) ||  (echo "NO")
)
0 голосов
/ 22 июля 2009

Вы можете преобразовать Perl-программу в .exe, который не будет нуждаться в perl с PAR :: Packer (возможно даже шифрование) Лучше всего использовать Strawberry Perl для Windows для работы с PAR :: Packer, но также возможно использование ActivePerl.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...