1

Тема: CMD: Экранирование восклицательного знака после enabledelayedexpansion

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

@echo off
set n=0
setlocal enabledelayedexpansion

for /f "tokens=* usebackq" %%i in (`dir "copy*.zip" /b /tc /o-d`) do (
    set /a n=!n! + 1
    echo !n!
    if /i !n! GEQ 15 (
        echo Deleted %%i
        del /f "%%i"
    )
)

2

Re: CMD: Экранирование восклицательного знака после enabledelayedexpansion

Не уверен, что подойдёт, но попробуйте воспользоваться этим: Оператор “!” или оператор “%”?. Или не используйте включение отложенного раскрытия переменных (раскрытие делать через вызов «call»). Либо, что будет более продуктивно, переходите на WSH/PoSH.

P.S. Насколько я помню, в «SET /A» использовать раскрытие (что «%», что «!») не требуется.

3

Re: CMD: Экранирование восклицательного знака после enabledelayedexpansion

Могу предложить следующий скрипт ротации файлов

@echo off

if    "%~1" == ""   goto help
if /i "%~1" == "/h" goto help

setlocal

if not "%~2" == "" set /a rotate_n=%~2 2>nul
if not defined rotate_n set rotate_n=5
if %rotate_n% lss 5 set rotate_n=5

:: set rotate_c=copy /y
set rotate_0=copy nul
set rotate_c=move /y

set rotate_i=%rotate_n%

:loop_redo
set /a rotate_i-=1
if %rotate_i% == 0 goto loop_break

if exist "%~1.%rotate_i%" %rotate_c% "%~1.%rotate_i%" "%~1.%rotate_n%"

set /a rotate_n-=1
goto loop_redo
:loop_break

%rotate_c% "%~1" "%~1.1" && %rotate_0% "%~1"

endlocal
goto :EOF

:help
echo.Usage:
echo.    %~n0 FILENAME [NUMBER]
goto :EOF

Можно вызывать из другого скрипта. По умолчанию создает 5 файлов, добавляя очередную цифру к расширению. Второй (необязательный) параметр указывает размер очереди.

@echo off

:: Очередь равна 15 для каждого "бекапируемого" файла
for /f "tokens=* usebackq" %%i in (`dir "a*.txt" /b /tc /o-d`) do (
    call rotate "%%~i" 15
)
( 2 * b ) || ! ( 2 * b )

4

Re: CMD: Экранирование восклицательного знака после enabledelayedexpansion

alexii
Спасибо за ссылку, нашел там идею о переменной, которой прсвоен восклицательный знак.
Вот мой код: он удаляет старые бэкапы, исходя из заданного в скрипте количества(сами бекапы создаются сторонней программой). В моем случае имя файла представляло "Copy date-time!.zip"

@echo off
set n=0
set ex=!
setlocal enabledelayedexpansion
set LogFile="%~dp0\LogRotation.log"


echo ============================================>>%LogFile%
echo %date% %time:~0,8%>>%LogFile%
echo ============================================>>%LogFile%

dir "copy*.zip" /b /tc /o-d>>%LogFile%
echo -------------------------------------------->>%LogFile%

for /f "tokens=* usebackq" %%i in (`dir "copy*.zip" /b /tc /o-d`) do (
    set /a n=!n! + 1
    if /i !n! GEQ 15 (
        echo Deleted "%%i!!ex!.zip">>%LogFile%
        del /f "%%i!!ex!.zip"
    )
)
rem echo Done. See "%LogFile%" for more details.