我一直在处理批处理脚本,要更改一些.xml
文件格式/类型。
这几乎已经完成,但我在更改时间码方面遇到了问题。
这是一个例子
<Events>
<Event In="00:00:20.650" Out="00:00:22.970"
<Event In="00:00:23.050" Out="00:00:26.300"
此时间格式hh:mm:ss.ms
应更改为hh:mm:ss:ff
表示将Milliseconds
更改为Frames
。
执行此操作的公式如下:ms*25/1000
或简单ms*0.025
输出应为
<Events>
<Event In="00:00:20:16" Out="00:00:22:24"
<Event In="00:00:23:01" Out="00:00:26:08"
备注
GNUWin
和Cygwin
库工具,因此可以使用bc
expr
,tr
,awk
{{ 1}}或任何解决方案来完成工作。我不确定这是否有很多要问,但任何形式的帮助都会很棒。
最好的问候
答案 0 :(得分:2)
您可以使用awk脚本执行此操作:
<强> script.awk 强>
{
re = "[0-9]{2}:[0-9]{2}:[0-9]{2}.([0-9]{3})"
while( match( $0, re, grps) ) {
frames = sprintf("%02.0f",( grps[1] *0.025 ) )
gsub( "." grps[1], ":" frames)
}
print
}
像awk -f script.awk yourfile
一样运行它。
它尝试匹配这样的时间戳并将最后一部分(毫秒)捕获到grps[1]
。然后计算完成,sprintf
用于格式化帧。
之后gsub
用帧替换毫秒。
答案 1 :(得分:2)
<强>的PowerShell:强>
[xml]$xml = gc events.xml
function fix([timespan]$ts) {
"{0}:{1:D2}" -f $ts.ToString("hh\:mm\:ss"),[int]($ts.Milliseconds * 0.025)
}
$xml.SelectNodes('//Event') | %{
$_.In = fix $_.In
$_.Out = fix $_.Out
}
$xml.Save("events_fixed.xml")
如果您希望将其作为批处理脚本,可以将其转换为Batch + PowerShell多语言,方法是将其插入顶部并使用.bat扩展名保存:
<# : batch portion
@echo off & setlocal
powershell "iex (${%~f0} | out-string)"
goto :EOF
: end Batch / begin PowerShell hybrid code #>
答案 2 :(得分:2)
这是一个纯粹的batch-file解决方案。此脚本对于cmd
具有特殊含义的所有字符都是安全的。基本上,它会在给定的输入文件中搜索关键字或属性名称In
和Out
,然后搜索=
以及用引号""
括起来的时间代码。如果找到,则将毫秒部分拆分,转换为帧并附加到剩余时间码,由:
分隔。每行可以有任意数量的时间码,只要它们的格式与样本数据中给出的格式相同,并且其中一个给定的关键字在前面,就可以识别和转换所有时间码。
该脚本支持舍入转换后的值 - 请参阅文件开头的变量定义rem
处的备注(FORMULA
)(在带有备注{{1的块中查找) }})。
这是代码:
Define constants here:
假设脚本保存为@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set KEYWORDS="In","Out" & rem // (provide a list of attribute names)
set "PATTERN=[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]"
set /A PLENGTH=12 & rem // (char. length of resolved `PATTERN` string)
set "FORMULA=(MS*25+0)/1000" & rem /* (`+0` means to round frames down;
rem use `+999` instead to round up, or `+500` to round to nearest) */
set /A PADDING=2 & rem // (number of digits of resulting frame value)
set "FILE=%~1"
if not defined FILE exit /B 1
for /F "delims=" %%L in ('findstr /N /R "^" "%FILE%"') do (
set "LINE=%%L"
setlocal EnableDelayedExpansion
set "LINE=!LINE:*:=!"
if defined LINE (
for /F delims^=^ eol^= %%E in ("!LINE!") do (
endlocal
set "LINE=%%E"
setlocal EnableDelayedExpansion
)
) else (
endlocal
set "LINE="
setlocal EnableDelayedExpansion
)
for %%P in (!KEYWORDS!) do (
endlocal
set "KEYWORD=%%~P"
call :PROCESS LINE LINE KEYWORD
setlocal EnableDelayedExpansion
)
echo(!LINE!
endlocal
)
endlocal
exit /B
:PROCESS rtn_string ref_string ref_key
setlocal EnableDelayedExpansion
set "COLL="
set "LINE=!%~2!"
set "KEYW=!%~3!"
:LOOP
if defined LINE (
call :LEN LLENGTH LINE
call :LEN KLENGTH KEYW
for /F delims^=^ eol^= %%T in ("!KEYW!") do (
set "SEEK=!LINE:*%%T=!"
)
if defined SEEK (
if not "!SEEK!"=="!LINE!" (
call :LEN SLENGTH SEEK
set /A TLENGTH=LLENGTH-^(SLENGTH+KLENGTH^)
for /F "tokens=1,2" %%M in ("!TLENGTH! !KLENGTH!") do (
set "DONE= !LINE:~,%%M!"
set "TEST=!LINE:~%%M,%%N!"
)
set "CHAR=!DONE:~-1!" & set "CHAR=!CHAR: = !"
set "DONE=!DONE:~1!"
if "!TEST!"=="!KEYW!" (
if "!CHAR!"==" " (
set "DONE=!DONE!!KEYW!"
set "TEST=!SEEK!"
set /A TLENGTH=PLENGTH+3
for /F %%N in ("!TLENGTH!") do (
set "TEST=!SEEK:~,%%N!" & set "SEEK=!SEEK:~%%N!"
)
echo(!TEST! | > nul findstr /R /C:^^^"^^^^^^^=\"!PATTERN!\"^^^ $^^^"
if not ErrorLevel 1 (
for /F "tokens=1,2 delims=." %%S in ("!TEST:~1!") do (
set "HHMMSS=%%~S" & set "MS=%%~T"
set /A "FF=%FORMULA%"
set "FF=0000!FF!" & set "FF=!FF:~-%PADDING%!"
)
set "COLL=!COLL!!DONE!="!HHMMSS!:!FF!"" & set "LINE=!SEEK!"
) else (
set "COLL=!COLL!!DONE!!TEST!" & set "LINE=!SEEK!"
)
) else (
set "COLL=!COLL!!DONE!!TEST!" & set "LINE=!SEEK!"
)
) else (
set "COLL=!COLL!!DONE!!TEST!" & set "LINE=!SEEK!"
)
) else (
set "COLL=!COLL!!LINE!" & set "LINE="
)
) else (
set "COLL=!COLL!!LINE!" & set "LINE="
)
goto :LOOP
)
if defined COLL (
for /F delims^=^ eol^= %%E in ("!COLL!") do (
endlocal
set "%~1=%%E"
setlocal EnableDelayedExpansion
)
) else (
endlocal
set "%~1="
setlocal EnableDelayedExpansion
)
endlocal
exit /B
:LEN rtn_length ref_string
setlocal EnableDelayedExpansion
set "STR=!%~2!"
if not defined STR (set /A LEN=0) else (set /A LEN=1)
for %%L in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if defined STR (
set "INT=!STR:~%%L!"
if not "!INT!"=="" set /A LEN+=%%L & set "STR=!INT!"
)
)
endlocal & set "%~1=%LEN%"
exit /B
,输入文件名为convert-ms-to-frames.bat
,输出文件名为sample.xml
,请使用以下命令行:
return.xml
只需删除convert-ms-to-frames.bat "sample.xml" > "return.xml"
部分即可在控制台上显示输出数据以进行测试。
假设输入文件> "return.xml"
包含以下数据......:
sample.xml
...输出文件<?xml version="1.0"?>
<Events>
<Event In="00:00:20.650" Out="00:00:22.970" />
<Event In="00:00:23.050" Out="00:00:26.300" />
</Events>
将包含以下数据:
return.xml
答案 3 :(得分:1)
使用bc
$ ms="650"
$ ff=$(echo ${ms} "*0.025/1" |bc)
$ echo $ff
16
当结果小于10时我留给你,以添加额外的“0”