如何在文本文件中用MB中的值替换GB中的所有值?

时间:2014-10-15 13:44:37

标签: batch-file

我需要读取一个文件,并用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行。如果你有一个更简单的方法,那就非常欢迎了!

1 个答案:

答案 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