我需要读取一个文件,并用GB中的值替换GB中的值。该值并不总是以GB为单位,大部分时间都是小数。我找到的唯一方法是:
for /F "tokens=1,2,3,4 delims=," %%A in (file.log) do (
echo.%%D|findstr "GB Available" >nul 2>&1
if errorlevel 0 if not errorlevel 1 (
set value=%%D
echo value:!value! REM looks like "Available= 12.53GB"
set value_short=!value:~11!
set value_short=!value_short: GB=! REM looks like "12.53"
echo value_short:!value_short!
set /a value_converted=!value_short:.=!*10
echo value_converted:!value_converted! MB REM looks like "1253 MB"
set "line=%%D"
set "line=!line: !value_short!=!value_converted!!"
echo LINE: !line! REM Need to have something like: "Available= 1253MB"
)
if errorlevel 1 (
echo no
)
)
不幸的是set "line=!line: !value_short!=!value_converted!!"
不起作用,我也试过用%而不是!但它不起作用。这条线有什么问题?
主要目标是在我的文件中以MB为单位,为此我读取文件并以MB为单位写入行而不在新文件中触及它们,并通过转换它们来重写GB行。如果你有一个更简单的方法,那就非常欢迎了!
答案 0 :(得分:1)
您假设GB值始终具有2个小数位,并且值单位使用1000的倍数而不是1024的倍数。我将假设这是正确的。
使用&&
(成功)和||
(失败)运算符的条件执行有一个更简单的表示法。
您的FINDSTR搜索不正确。它将匹配包含GB
或 Available
的任何行。您想要 和 。我会使用正则表达式搜索`“^ Available =。* GB $”。
您的REMark声称源值为12.53GB
,但您的代码暗示它是12.53 GB
。我将假设你的代码是正确的,并且在GB之前有一个空格。您的代码还假定数字前总是有空格。我也会认为这是正确的。
您的失败线路需要两层变量扩展。必须在外部变量扩展之前扩展搜索和替换术语。如果你不在代码块中,%var%
会起作用,但你是,所以它不会。解决方案是将值传输到FOR变量。
for %%A in ("!value_short!") do for %%B in ("!value_converted!") do set "line=!line:%%~A=%%~B!"
如果其中任何一个值包含*
或?
,则您必须切换为使用("string")
值的FOR / F.
但是有一种更简单的方法可以完成你的任务。
for /F "tokens=1-4 delims=," %%A in (file.log) do (
for /f "tokens=1-4 delims=. " %%a in ("%%D") do if "%%a"=="Available=" if "%%d"=="GB" (
set "line=%%a %%b%%c0 MB"
echo !line!
) else (
echo no
)
)
以上内容仅修复了您现有的代码 - 它不会替换原始文件中的任何值。
我不会使用上述任何纯批处理来修改文件。相反,我会使用a hybrid JScript/batch utility called REPL.BAT在stdin上执行正则表达式搜索/替换,并将结果写入stdout。它是纯脚本,可以在任何Windows机器上从XP开始本地运行。
type "file.log" | repl "(Available= )([0-9]+)\.([0-9][0-9]) GB" "$1$2$30 MB" >"file.log.new"
move /y "file.log.new" "file.log" >nul