批处理 for 循环中的复杂转义编码

批处理 for 循环中的复杂转义编码

参考https://superuser.com/a/1508668/1884857

在我的代码中我添加了呕吐代码进入 for 循环。但是,代码停在以下行:

ECHO [int]$Calculation.split("%MathType%")[0] %MathType% [int]$Calculation.split("%MathType%")[1] >> "%PSScript%"

运行批处理的错误输出是:
[0] 此时是出乎意料的。

因此,我的问题是如何使代码在 for 循环中运行(例如循环遍历文件夹中的文件)?

我尝试过各种逃脱方法,例如

ECHO [int]$Calculation.split("!MathType!")[0] !MathType! [int]$Calculation.split("!MathType!")[1] >> "!PSScript!"

可悲的是,仍然没有运气。

如有任何想法我将不胜感激。

这是来自另一篇文章的原始代码:

SET "Calculation=3*1073741824"
SET "MathType=*"
    
SET PSScript=%temp%\PS~MathTemp.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
ECHO $Calculation = "%Calculation%" > "%PSScript%"
ECHO [int]$Calculation.split("%MathType%")[0] %MathType% [int]$Calculation.split("%MathType%")[1] >> "%PSScript%"
    
For /F "Delims=" %%I IN (`Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%'"`) Do Set "nCalc=%%I"

编辑:@io-io 解决了!为了完整起见,这是我的完整脚本。它扫描文件列表中的所有视频文件并使用 ffmpeg 处理它们。


REM Change the console encoding to UTF-8 (for Nordic characters).
chcp 65001 | echo/

set filelist=%1
echo %filelist%

REM Define ESC escape character
for /f %%d in ('echo prompt $E ^| cmd') do (set "ESC=%%d")

REM Loop through all video files lists in a separate filelist
for /f "usebackq tokens=*" %%a in ("%filelist%") do (
    call :StartTimer
    set Bytes=%%~za

    REM Below timestamp coding depends on locale setting on computer
    set Timestamp=%%~ta
    set TSYYYY=!Timestamp:~6,4!
    set TSYY=!Timestamp:~8,2!
    set TSMM=!Timestamp:~3,2!
    set TSDD=!Timestamp:~0,2!
    set TSHR=!Timestamp:~11,2!
    set TSMIN=!Timestamp:~14,2!
    set TSDato=!TSYY!!TSMM!!TSDD!
    set TSTid=!TSHR!!TSMIN!
    
    REM Display information about input file
    echo !ESC![92;103mInputfile="%%~fa"!ESC![0m
    echo !ESC![92;103mInputfile size=!Bytes! Bytes!ESC![0m

    REM Convert to MP4 if needed, and compress to iPhone supported HEVC format
    echo !ESC![91mConvert %%~xa file to MP4 format, and compress to iPhone supported HEVC format!ESC![0m
    ffmpeg -n -hide_banner -loglevel quiet -i "%%~fa" -vcodec libx265 -vsync 0 -vtag hvc1 -crf 28 "%%~dpna_!TSDato!-!TSTid!.mp4"
    REM Reset Console command after running ffmpeg
    chcp 65001 | echo/

    REM Find size of new file
    FOR /F "tokens=*" %%b IN ("%%~dpna_!TSDato!-!TSTid!.mp4") DO set OutBytes=%%~zb
    
    **REM Find compression ratio new vs old file
    SET "Calculation=!OutBytes!/!Bytes!"
    SET "MathType=/"
    SET PSScript=%temp%\PS~MathTemp.ps1
    IF EXIST "!PSScript!" DEL /Q /F "!PSScript!"
    ECHO $Calculation = "!Calculation!" > "!PSScript!"
    ECHO [int]$Calculation.split("!MathType!"^)[0] !MathType! [int]$Calculation.split("!MathType!"^)[1] >> "!PSScript!"
    FOR /F "USEBACKQ DELIMS=" %%c IN (`Powershell -ExecutionPolicy Bypass -Command "& '!PSScript!'"`) DO SET "Compression=%%c"**
    
    REM Display compression summary
    echo !ESC![42mSummary!ESC![0m
    echo !ESC![32mInputfile="%%~fa"!ESC![0m
    echo !ESC![32mInputfile size=!Bytes! Bytes!ESC![0m
    echo !ESC![32mOutputfile="%%~dpna_!TSDato!-!TSTid!.mp4"!ESC![0m
    echo !ESC![32mOutputfile size=!OutBytes! Bytes!ESC![0m
    echo !ESC![32mCompression rate=!Compression!!ESC![0m
    echo !ESC![42mFile "%%~a" optimisation complete!ESC![0m

    REM Clean up. If new file created, delete original file
    if NOT exist "%%~dpna_!TSDato!-!TSTid!.mp4" (
        echo !ESC![33mNo optimization has been performed!ESC![0m
    ) else (
        del "%%~fa"
        echo !ESC![47;91mOriginal file has been DELETED!ESC![0m
    )
    call :StopTimer
    call :DisplayTimerResult
    REM pause >nul
);=

echo. & echo All files optimised! & endlocal

REM https://stackoverflow.com/questions/4313897/timer-in-windows-batch-file
:StartTimer
:: Store start time
set StartTIME=%TIME%
for /f "usebackq tokens=1-4 delims=:., " %%f in (`echo %StartTIME: =0%`) do set /a Start100S=1%%f*360000+1%%g*6000+1%%h*100+1%%i-36610100
goto :EOF

:StopTimer
:: Get the end time
set StopTIME=%TIME%
for /f "usebackq tokens=1-4 delims=:., " %%f in (`echo %StopTIME: =0%`) do set /a Stop100S=1%%f*360000+1%%g*6000+1%%h*100+1%%i-36610100
:: Test midnight rollover. If so, add 1 day=8640000 1/100ths secs
if %Stop100S% LSS %Start100S% set /a Stop100S+=8640000
set /a TookTime=%Stop100S%-%Start100S%
set TookTimePadded=0%TookTime%
goto :EOF

:DisplayTimerResult
:: Show timer start/stop/delta
echo Started: %StartTime%
echo Stopped: %StopTime%
echo Elapsed: %TookTime:~0,-2%.%TookTimePadded:~-2% seconds
goto :EOF```

答案1

@echo off

set "_Math=*"
set "_Calc=3*1073741824"    
set "_PSSctr=%tmp%\PS~MathTemp.ps1"

2>nul del /q /f "%_PSSctr%"

> "%_PSSctr%" (
     echo/$Calc = "%_Calc%"
     echo/[int]$Calc.split("%_Math%"^)[0] %_Math% [int]$Calc.split("%_Math%"^)[1]
    )
    
For /F "Usebackq Delims=" %%i in (`
     Powershell -ExecutionPolicy Bypass -Command "& '%_PSSctr%'"
    `) do set "_nCalc=%%~i"

echo/%_nCalc%

1.您对原始代码进行了更改,在原始循环的执行中更改" ' "" ` "For /F(' ... ')(` ... `)

2.您需要的转义符位于echo ...包含结束符的位置),并且仅在的结束符中^),此外,如果您要使用,请在循环中`添加UsebackqFor /f

相关内容