如何为修改JVM命令行的批处理脚本添加文件校验替换逻辑?
批处理脚本的校验替换逻辑实现
原脚本已实现:逐行读取源批处理文件,定位以java.exe开头且包含特定结尾子串的行,在结尾子串前插入config.ini中定义的JVM开关后生成新文件,未匹配行原样输出。现需新增校验逻辑,仅满足以下两个条件时,才用新文件替换源文件:
- 新文件大小等于源文件大小加上插入字符的总长度
- 源文件与新文件的大小差异占比极小(可自定义阈值)
修改后的完整脚本
@echo off setlocal enabledelayedexpansion set sourcefile=my_source_script.bat set "newfile=new_%sourcefile%" :: 定义差异占比阈值(0.001代表0.1%) set "size_diff_threshold=0.001" set modify_count=0 :: Create the destination file type NUL > "%newfile%" :: Define the part to be inserted in the JVM Command Line :: The switches to be inserted are defined in config.ini file call :load_config echo insert switches value = %INSET_JVM_SWITCHES% :: 计算单次插入的字符长度(包含空格) set "insert_len=0" if defined INSET_JVM_SWITCHES ( set "insert_str=!INSET_JVM_SWITCHES! " :: 用临时文件计算字符串长度 echo(!insert_str!>tmp_len.tmp for %%f in (tmp_len.tmp) do set insert_len=%%~zf del tmp_len.tmp :: 减去Windows换行符的2字节(CR+LF) set /a insert_len-=2 ) REM Define the first and last part which will be used to identify the lines to be modified in the batch script set "firstpart=java.exe" set "lastpart=com.main.java.class.of.the.application -auto" REM Read source line by line and prefix with line number to pick empty lines FOR /f "delims=" %%l IN ('findstr /N "^" ".\%sourcefile%"') DO ( set "line=%%l" REM Remove the line number until the column set "line=!line:*:=!" REM Initialize left and right parts. This is needed to identify the lines to be modified set "left=x" if not "!line!"=="" for %%b in ("!lastpart!") do set "left=x!line:%%~b=!" if not "!line!"=="" for %%b in ("!firstpart!") do set "left=x!line:%%~b=!" set "right=x!line!" REM If firstpart and lastpart are found in line ... if not "!line!"=="" if not !left!==!right! ( REM Update the line by replacing the last part with the addition plus the last part for %%b in ("!lastpart!") do set "line=!line:%%~b=!INSET_JVM_SWITCHES! %%~b!" set /a modify_count+=1 ) REM Write the line to the new batch script echo(!line!>>"%newfile%" ) :: 开始执行校验与替换逻辑 echo. echo --- 开始校验文件 --- :: 获取源文件和新文件大小 for %%f in ("%sourcefile%") do set "source_size=%%~zf" for %%f in ("%newfile%") do set "new_size=%%~zf" echo 源文件大小: %source_size% 字节 echo 新文件大小: %new_size% 字节 echo 修改行数: %modify_count% echo 单次插入长度: %insert_len% 字节 :: 计算预期新增总长度 set /a expected_add=modify_count * insert_len echo 预期新增长度: %expected_add% 字节 :: 校验条件1:新文件大小等于源文件大小+预期新增长度 set condition1=0 if %new_size% equ %source_size% ( if %expected_add% equ 0 set condition1=1 ) else ( set /a calc_size=source_size + expected_add if %new_size% equ %calc_size% set condition1=1 ) :: 校验条件2:差异占比小于阈值(避免源文件为0的极端情况) set condition2=0 if %source_size% gtr 0 ( :: 计算差异值(取绝对值) set /a diff= new_size - source_size if !diff! lss 0 set /a diff= -diff :: 用powershell完成浮点计算差异占比 for /f %%r in ('powershell "!diff! / !source_size!"') do set "diff_ratio=%%r" :: 比较占比与阈值 for /f %%r in ('powershell "!diff_ratio! -lt !size_diff_threshold!"') do set condition2=%%r ) else ( :: 源文件为空时,只有新文件也为空才通过 if %new_size% equ 0 set condition2=1 ) echo. echo 条件1(大小匹配预期): %condition1% echo 条件2(差异占比极小): %condition2% :: 满足两个条件则执行替换 if %condition1% equ 1 if %condition2% equ 1 ( echo 校验通过,执行替换... del "%sourcefile%" ren "%newfile%" "%sourcefile%" echo 替换完成 ) else ( echo 校验不通过,保留原文件与新文件 ) goto :eof ::************************************************************************************** :: Function: Load Config :: Purpose: Parse the text file config.ini :load_config echo. echo Loading config data from config.ini file ... echo. SET "configfile=config.ini" if not exist %configfile% ( echo Error: The following config file was not found: echo %configfile% exit /b 1 ) set "uniqueList=" :: remove variables starting count_ FOR /F "delims==" %%e In ('set count_ 2^>Nul') DO SET "%%e=" FOR /f "usebackq tokens=1* delims==" %%b IN ("%configfile%") DO ( IF "%%c" neq "" ( set keyname=%%b IF DEFINED count_!keyname! (SET /a count_%%b+=1) ELSE (SET /a count_!keyname!=0 & set uniqueList=!uniqueList!,!keyname!) if "!keyname:~-4!"=="_arr" ( SET "!keyname![!count_%%b!]=%%c" ) else ( SET "!keyname!=%%c" ) ) ) :: Remove first char if it is a coma , if "!uniqueList!" neq "" if "!uniqueList:~0,1!" equ "," set uniqueList=!uniqueList:~1! echo Completed parsing the config file. echo. goto :eof ::****************************************************************
关键逻辑说明
- 统计修改行数:在匹配到需要插入JVM开关的行时,通过
modify_count变量累计修改次数 - 计算插入长度:将插入字符串写入临时文件,通过文件大小获取字符串长度(减去Windows换行符的2字节)
- 文件大小校验:
- 计算预期新增总长度:
修改次数 × 单次插入长度 - 对比新文件实际大小与
源文件大小+预期新增长度是否一致
- 计算预期新增总长度:
- 差异占比校验:借助PowerShell完成浮点计算,判断大小差异占源文件的比例是否小于设定阈值(默认0.1%)
- 替换操作:仅当两个条件都满足时,删除源文件并将新文件重命名为源文件名
内容的提问来源于stack exchange,提问作者tarekahf
相关产品推荐
相关产品推荐

