我正在使用wget的DOS端口从API收集数据,以生成日志文件的数据(将在以后进行分析)。 API提供了我需要的所有信息,除了当前时间(它在数据流开始时提供时间,但在此之后不再提供时间)。
API最初提供10行数据,然后每20-30秒提供一行。
我正在尝试为此输出添加时间戳并将其复制到日志文件中 - 我不介意时间戳与输出的其余部分或之前的行位于同一行。
我首先开始使用这个批处理文件:
addtimes.bat:
@echo off >nul
:start
set /p input="":
echo %time%
echo %input%
goto:start
(称为“wget ..... | addtimes.bat> log.log”)
然而,这些数据丢失了 - 许多行数据的开头都丢失了。
我在这里看到并意识到我应该使用for循环。
addtimes2.bat:
@echo off
cls
setlocal EnableDelayedExpansion
for /F "tokens=*" %%a in ('more') do (
echo !time! %%a )
)
我尝试过使用和不启用延迟扩展。
我似乎无法使用不同的时间戳一次传递一行信息 - 一旦关闭数据流,我的所有行都会得到相同的时间戳。
典型输入数据的格式为:
[1,"219","265",14528,1359031137000,1359031137000]
[1,"6594","358",18188,1359031019000,1359031019000]
[1,"690","94",15920,1359031534000,1359031534000]
[1,"25164","102",2129,1359031457000,1359031457000]
[1,"3488","329",2109,1359030868000,1359030868000]
[1,"37247","6",11506,1359031223000,1359031223000]
您可能会注意到数据中有UTC时间,但它们不是当前时间。
答案 0 :(得分:4)
我不相信您可以使用纯原生批次获得您想要的结果。所有时间都相同的原因是FOR / F循环不会处理任何输入行,直到整个输入流被缓冲(管道左侧的命令已经完成)。 FOR / F命令等待直到收到所有输入,然后在一次狂奔中转储每一行。如果输入流足够大,您将获得轻微的时间变化,但在原始命令生成每一行时,没有任何表示接近。
这是一个混合的JScript /批处理脚本,可以执行您想要的操作。它可以作为一个直接的JScript文件工作,但是你需要明确地使用CSCRIPT。混合方法使实用程序更方便。
将其命名为addtimes.bat,并像以前一样使用它。
@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment
::************ Batch portion ***********
@echo off
cscript //E:JScript //nologo "%~f0"
exit /b 0
************* JScript portion **********/
while (!WScript.StdIn.AtEndOfStream) {
var ts = new Date()
var ms = (ts.getTime() % 1000)
WScript.Stdout.WriteLine(
ts.getFullYear() + "-" +
((ts.getMonth()<9)?"0":"") + (ts.getMonth()+1) + "-" +
((ts.getDate()<10)?"0":"") + ts.getDate() + " " +
((ts.getHours()<10)?"0":"") + ts.getHours() + ":" +
((ts.getMinutes()<10)?"0":"") + ts.getMinutes() + ":" +
((ts.getSeconds()<10)?"0":"") + ts.getSeconds() + "." +
((ms<10)?"00":((ms<100)?"0":"")) + ms + " - " +
WScript.StdIn.ReadLine()
);
}
的修改
wmz有一个非常聪明的 和危险的 解决方案。该解决方案可以简化 - 无需使用自动运行功能。
警告 - 正如wmz所说,如果输出中的任何行以可执行命令或程序名开头,则下面的解决方案会产生非常糟糕的后果!我不建议实际使用此解决方案,但我发现它非常有趣。
(echo @prompt $D $T -$S & YourCommandHere )|cmd 2>nul|findstr /rbc:"../../.... ..:..:..\... - " >log.log
添加FINDSTR管道以去除CMD头信息,初始PROMPT命令以及CMD在每个“命令”之后插入的不需要的空白行。 FINDSTR正则表达式可能需要更改以匹配您选择的提示和区域设置的细节。
答案 1 :(得分:3)
请注意:这可能会产生很多副作用(或根本不起作用,或使您的系统不稳定等)并且未经过测试。这比批量运动更多是
编辑:请参阅debenham的回答,了解如何使用这个想法。
prompt $T
),请将提示设置为时间(prompt $D $T
)或日期时间。您必须在注册表中的Autorun
键(HKEY_CURRENT_USER\software\Microsoft\Command Processor
)中执行此操作,因此它是默认值。如果没有自动运行键,则创建它(它包含打开cmd提示时执行的命令)cmd.exe
,并将其输出重定向到文件:more | cmd 2>nul >timestamped.log
(您在我使用more
的地方使用您的命令)。使用more
,输入:这是一条消息 这是时间戳^ Z
在timestamped.log中生成以下行(在具有cmd处理器版本信息的两行之后):
23:19:57,17_这是一条信息 23:19:59,95_是时间戳的
这是有效的,因为cmd会尝试执行您的日志条目。这失败了(错误消息被抑制/发送到nul),但同时与提示(时间/日期)一起回显。
如果您的日志消息未被引用,则必须非常小心(或更一般地说,如果您不确定其格式,或者它们不是在您的直接控制下创建的< / em>) - 如果您的行恰好以一个有效命令的单词开头 - 它将被执行!