windows - batch: unwanted newline character after echo of a delayed parameter -


this part of batch uses wmic.exe print text containing different system information. in 1 part use calls , labels make automated parameters hard disk information had use parameters within parameters work. works delayed expansions enabled. in /f loop containing code echoes file lines being echoed , has delayed expansion in them echoes newline character directly after end of expansion! don't know why or how go around this. , have set mind on doing batch , yes know lot easier wmi in vbs script. appreaciated

@echo off  /f "skip=2 delims=" %%a in ('wmic diskdrive medialoaded') call :getdisk  /f "skip=2 delims=" %%a in ('wmic diskdrive medialoaded') call :setdisk  >%tmp%\t.x echo wscript.echo round^(wscript.arguments^(0^) / ^(1024 * 1024 * 1024^), 1^)  /f "skip=2 delims=" %%a in ('wmic diskdrive medialoaded') call :numdisk  goto:eof  :getdisk set /a disk=%disk%+1 goto:eof  :setdisk if not defined numreset set /a numreset=%disk%-1 if not defined num (set num=0) else (set /a num=%num%+1) /f "tokens=1-10 delims==" %%a in ('wmic diskdrive %num% interfacetype^,model^,size /format:list') set %%a%num%=%%b if "%num%"=="%numreset%" set "num=" goto:eof  :numdisk if not defined num (set num=0) else (set /a num=%num%+1) set /a hdd=%num%+1 setlocal enabledelayedexpansion set interfacetype=interfacetype%num% set mediatype=mediatype%num% set size=size%num% if "%disk%" geq "%num%" >>hdd.txt echo hdd %hdd%:      index %num% if "%disk%" geq "%num%" >>hdd.txt echo interface:  !%interfacetype%! if "%disk%" geq "%num%" >>hdd.txt echo mediatype:  !%mediatype%! if "%disk%" geq "%num%" /f %%a in ('cscript //nologo //e:vbscript %tmp%\t.x "!%size%!"') set sizegb=%%a if "%disk%" geq "%num%" >>hdd.txt echo size:       !%size%! b ^(%sizegb% gb^) if "%disk%" geq "%num%" >>hdd.txt echo. endlocal goto:eof 

workaround:

since linefeed inside expanded variable simple remove it:

::before: !%var%!  ::after: !%var%:~0,-1! 

omg! code horrifically , needlessly complex , inefficient - can barely follow logic. more power getting work, think can show better way :)

first off, not newline or linefeed (<lf>, hex 0x0a, decmal 10), carriage return (<cr>, hex 0x0d, decimal 13). unwanted character odd artifact of how /f interacts unicode output of wmic. /f attempts convert unicode ansi, somehow terminates each line of output <cr><cr><lf>. /f ends each line before <lf>, strips last character if happens <cr>, leaves 1 unwanted trailing <cr> @ end of every line.

one foolproof way eliminate unwanted character use /f, since strip last character if <cr>:

for /f "delims=" %%a in ('wmic ...') /f "youroptions" %%b in ("%%a") ... 

the nice thing method not require delayed expansion.

but since using delayed expansion, method of setting variable , using substring operation trim off last character works fine.


now onto developing more sensible code base desired result:

there no need parse wmic output multiple times - can within single /f loop executes wmic once.

instead of list format, can use csv. puts of needed values disk drive on 1 line, comma delimited. drawback there empty values, cause problems /f parsing, consecutive delimiters treated one, tokens missed. trick use search , replace put quotes around each token. missing value becomes ,"",, can parsed second /f. use %%~a later strip quotes each token.

your wmic command gets model, don't use, , output references media type, did not get. fixed code , output both.

you run different wmic each disk index, wmic diskdrive provides index value can get, why not use it. output not sorted in index order, info there. if needed, additional code added sort results index.

it more efficient enclose outer /f within parentheses , redirect output once.

finally, there no need temporary vbs script math. easy embed , call jscript within batch script instead.

@if (@x)==(@y) @end /* harmless hybrid line begins jscrpt comment  ::************ batch portion *********** @echo off setlocal enabledelayedexpansion set cnt=0 (   /f "skip=2 delims=" %%a in (     '"wmic diskdrive interfacetype,model,size,index,mediatype /format:csv"'   ) (     set "ln=%%a"     set "ln=!ln:~0,-1!"     set "ln="!ln:,=","!""     set /a cnt+=1     /f "tokens=2-6 delims=," %%b in ("!ln!") (       echo hdd !cnt!: index %%~b       echo interface: %%~c       echo model: %%~e       echo media: %%~d       set "size="       if %%f neq "" /f %%n in (         'cscript //e:jscript //nologo "%~f0" "math.round(%%~f/1024/1024/1024*10)/10"'       ) set "size=%%n gib"       echo  size: !size!       echo(     )   ) )>hdd.txt exit /b  ************ jscript portion ***********/ wscript.stdout.writeline(eval(wscript.arguments.unnamed(0))); 

edit: realized model description might include commas, cause problems /f parsing csv format. here solution reverts list format. turns out code simpler :)

i use second /f trick remove unwanted trailing <cr>.

@if (@x)==(@y) @end /* harmless hybrid line begins jscrpt comment  ::************ batch portion *********** @echo off setlocal enabledelayedexpansion set cnt=0 (   /f "delims=" %%l in (     '"wmic diskdrive interfacetype,model,size,index,mediatype /format:list"'   ) /f "tokens=1* delims==" %%a in ("%%l") (     if %%a equ index (       if !cnt! gtr 0 echo(       set /a cnt+=1       echo hdd !cnt!: index %%b     ) else if %%a equ size (       set "size="       if "%%b" neq "" /f %%n in (         'cscript //e:jscript //nologo "%~f0" "math.round(%%b/1024/1024/1024*10)/10"'       ) set "size=%%n gib"       echo %%a: !size!     ) else echo %%a: %%b   ) )>hdd.txt exit /b  ************ jscript portion ***********/ wscript.stdout.writeline(eval(wscript.arguments.unnamed(0))); 

Comments

Popular posts from this blog

javascript - jquery or ashx not working -

opencv - DataType<cv::detail::deriv_type>::depth what is it used for -

python 3.x - Mapping specific letters onto a list of words -