.BAT - 将字符串变量中的数字转换为基数为10的整数变量

时间:2012-11-01 10:42:49

标签: string variables batch-file integer

@echo off
rem ffmpeg -i test.ts 2>&1 | find "Duration" > duration.txt
rem set /p duration=<duration.txt

set duration=  Duration: 01:09:52.59, start: 0.136811, bitrate: 10740 kb/s

set /a Hours=%duration:~12,2%
set /a Mins=%duration:~15,2%
set /a Secs=%duration:~18,2%

set /a Duration_In_Seconds=(hours*3600)+(mins*60)+secs

echo %duration_In_seconds%

当我尝试将“09”设置为名为mins的整数变量时,它失败了。

号码无效。数字常量可以是十进制(17),十六进制(0x11)或八进制(021)。

我需要将字符串转换为整数,这样我就可以使用一些基本的数学来计算持续时间(以秒为单位)

2 个答案:

答案 0 :(得分:2)

从命令提示符处读取SET帮助(键入HELP SET),您将看到SET始终将零前缀数字解释为八进制。没有任何设置会强制基数10.相反,您必须操纵字符串,使其不以零开头。

无需写入临时文件。您可以使用FOR / F来解析输出,它也可以将输出分解为小时,分钟和秒标记。

我知道有两种简单的方法来绕过前导0。

一种方法是在值前加1,然后使用mod(余数)运算符提取所需的数字。在您的情况下,小时数将被限制为最大值99.如果您需要支持最多999,那么您可以前缀10并取mod为1000.请注意,可以使用单个SET /执行多个分配使用,分隔每个作业的声明。 SET / A服从正确的优先顺序,因此不需要括号。

@echo off
for /f "tokens=2-4 delims=:. " %%A in ('ffmpeg -i test.ts 2^>^&1 ^| find "Duration"') do (
  set /a Hours=1%%A%%100, Mins=1%%B%%100, Secs=1%%C%%100, Duration_In_Seconds=Hours*3600+Mins*60+Secs
)

另一种方法是使用FOR / F循环去除前导零。我追加1然后除以10,这样一串只有0的零仍然被处理。

@echo off
for /f "tokens=2-4 delims=:. " %%A in ('ffmpeg -i test.ts 2^>^&1 ^| find "Duration"') do (
  for /f "delims=0" %%N in ("%%A1") do set /a Hours=%%N/10
  for /f "delims=0" %%N in ("%%B1") do set /a Mins=%%N/10
  for /f "delims=0" %%N in ("%%C1") do set /a Secs=%%N/10
  set /a Duration_In_Seconds=Hours*3600+Mins*60+Secs
)

如果需要,如果小数秒大于或等于0.5,则很容易扩展代码以使秒数向上舍入。只需添加,作为分隔符来解析额外的令牌,然后添加一些数学技巧来进行舍入。

@echo off
for /f "tokens=2-5 delims=:., " %%A in ('ffmpeg -i test.ts 2^>^&1 ^| find "Duration"') do (
  for /f "delims=0" %%N in ("%%A1") do set /a Hours=%%N/10
  for /f "delims=0" %%N in ("%%B1") do set /a Mins=%%N/10
  for /f "delims=0" %%N in ("%%C%%D1") do set /a Secs=(%%N+500)/1000
  set /a Duration_In_Seconds=Hours*3600+Mins*60+Secs
)

答案 1 :(得分:0)

使用十六进制到十进制转换,以下代码适用于[0..39999]范围内的数字:

set str=000039999
set /a dgt=0x!str!
set /a "dgt=(10000*(dgt&983040)>>16)+(1000*(dgt&61440)>>12)+(100*(dgt&3840)>>8)+(10*(dgt&240)>>4)+(dgt&15)"
echo str="!str!"
echo dgt="!dgt!"