Войти

Показать полную графическую версию : Непонятное поведение переменных внутри FOR


dasgespenst
22-06-2015, 22:09
Делаю маленький скриптик для подготовки к бекапу. Только вот поведение этого скриптика совершенно неадекватное.

FOR /r %%A in ("*") DO (

set MYFILE=%%A
echo %MYFILE%| findstr /I /R "Txt$"
If %ERRORLEVEL% EQU 0 echo txt exist

echo %MYFILE%| findstr /I /R "Cmd$"
If %ERRORLEVEL% EQU 0 echo cmd exist

)

Внутри папки файлы archive.cmd и новый текстовой документ.txt

C:\archive>archive.cmd

C:\archive>FOR /R %A in ("*") DO (
set MYFILE=%A
echo | findstr /I /R "Txt$"
If 0 EQU 0 echo txt exist
echo | findstr /I /R "Cmd$"
If 0 EQU 0 echo cmd exist
)

C:\archive>(
set MYFILE=C:\archive\archive.cmd
echo | findstr /I /R "Txt$"
If 0 EQU 0 echo txt exist
echo | findstr /I /R "Cmd$"
If 0 EQU 0 echo cmd exist
)
txt exist
cmd exist

C:\archive>(
set MYFILE=C:\archive\Новый текстовый документ.txt
echo | findstr /I /R "Txt$"
If 0 EQU 0 echo txt exist
echo | findstr /I /R "Cmd$"
If 0 EQU 0 echo cmd exist
)
txt exist
cmd exist

C:\archive>archive.cmd

C:\archive>FOR /R %A in ("*") DO (
set MYFILE=%A
echo C:\archive\Новый текстовый документ.txt | findstr /I /R "Txt$"
If 1 EQU 0 echo txt exist
echo C:\archive\Новый текстовый документ.txt | findstr /I /R "Cmd$"
If 1 EQU 0 echo cmd exist
)

C:\archive>(
set MYFILE=C:\archive\archive.cmd
echo C:\archive\Новый текстовый документ.txt | findstr /I /R "Txt$"
If 1 EQU 0 echo txt exist
echo C:\archive\Новый текстовый документ.txt | findstr /I /R "Cmd$"
If 1 EQU 0 echo cmd exist
)
C:\archive\Новый текстовый документ.txt

C:\archive>(
set MYFILE=C:\archive\Новый текстовый документ.txt
echo C:\archive\Новый текстовый документ.txt | findstr /I /R "Txt$"
If 1 EQU 0 echo txt exist
echo C:\archive\Новый текстовый документ.txt | findstr /I /R "Cmd$"
If 1 EQU 0 echo cmd exist
)
C:\archive\Новый текстовый документ.txt

C:\archive>


Вот так вот получаю два совершенно неадекватных, притом разных выхлопа. Откуда такое странное поведение?

Foreigner
22-06-2015, 22:33
setlocal /?


@echo off
setlocal enabledelayedexpansion

FOR /r %%A in ("*") DO (

set MYFILE=%%A
echo !MYFILE! | 1>nul findstr /I /R "Txt$" && echo txt exist
echo !MYFILE! | 1>nul findstr /I /R "Cmd$" && echo cmd exist

)

Но зачем вообще переменная MYFILE, когда можно сразу обрабатывать %%A ? Да и findstr здесь не нужен, можно просто if exist *.txt

if /?

dasgespenst
22-06-2015, 22:41
>Но зачем вообще переменная MYFILE, когда можно сразу обрабатывать %%A ?

Это я переменные обкатываю.

>Да и findstr здесь не нужен, можно просто if exist *.txt

findstr пригодится тоже.

А что такое восклицательные знаки вокруг MYFILE? И пробел после MYFILE! не попадает в пайп?

PS: Да точно, пробел лишний :)

Спасибо.

Foreigner
22-06-2015, 22:50
dasgespenst, Ну можно либо так:

echo !MYFILE!| 1>nul findstr /I /R "Txt$" && echo txt exist

Либо так:

echo !MYFILE! | 1>nul findstr /I /R "\.Txt" && echo txt exist

Iska
22-06-2015, 22:53
dasgespenst, Ваши «%MYFILE%» и «%ERRORLEVEL%», находящиеся внутри скобок, будут раскрыты в момент вхождения в скобки, посему надо использовать отложенное раскрытие переменных окружения (см. пост #2 (http://forum.oszone.net/post-2521283.html#post2521283)). И «if %errorlevel% equ 0 …» имеет смысл заменить на оператор «&&», как показано там же.

dasgespenst
22-06-2015, 23:06
кстати без MYFILE с использрванием "А", я получаю странную ошибку "Достигнут уровень рекурсии, максимально возможный для команды SETLOCAL."

А как можно if exist "*.txt" туда добавить, ему вроде сам файл надо указывать?

Foreigner
22-06-2015, 23:42
dasgespenst,

@echo off
setlocal

FOR /r %%A in (*) DO (

echo %%A| 1>nul findstr /I /R "Txt$" && echo txt exist
echo %%A| 1>nul findstr /I /R "Cmd$" && echo cmd exist

)


@echo off
setlocal

FOR /r /d %%i in (.) DO (

if exist "%%i\*.txt" echo txt exists

)

dasgespenst
28-06-2015, 18:16
А как в подпрограмму добавить FOR? У меня FOR воспринимается как EOF.

Foreigner
28-06-2015, 19:33
dasgespenst, вопрос не понятен, поконкретней.




© OSzone.net 2001-2012