Windows批处理文件如何将输出重定向到带有日期/时间的日志文件?

4

我正在尝试运行一个批处理文件,它运行一个可执行文件并将其输出重定向到日志文件。日志文件的名称必须以日期和时间作为文件名。这是我使用的命令:

"%PROGRAMFILES%\PostgreSQL\9.4\bin\vacuumdb.exe" --username postgres --verbose --analyze --all > E:\Logs\VacuumDB\%date:~10,4%_%date:~4,2%_%date:~7,2%_%time:~0,2%_%time:~3,2%_%time:~6,2%.log 2>&1

这个命令在cmd中直接粘贴可以正常工作。日志文件会按预期创建,名称为“2015_06_25__11_20_46.log”。但是,当将其粘贴到批处理文件中并在cmd中运行时,它将被解释成如下形式:

"C:\Program Files\PostgreSQL\9.4\bin\vacuumdb.exe" --username postgres --verbose --analyze --all  8_21_42.log  1>E:\Logs\VacuumDB\2015_06_26_ 2>&1

请注意,文件名已被截断,时间现在附加到命令参数中,而不是在文件名中。所以显然命令失败了。
这肯定是非常简单的事情,但我没有找到任何解决方法。非常感谢您的帮助。
谢谢!

1
尝试使用> "E:\Logs\VacuumDB\%date:~10,4%_%date:~4,2%_%date:~7,2%_%time:~0,2%_%time:~3,2%_%time:~6,2%.log" 2>&1 - npocmaka
4个回答

7
以下是不使用SET命令的内联版本:
C:\test.bat > C:\log\test_%date:~10%%date:~4,2%%date:~7,2%-%time:~0,2%%time:~3,2%%time:~6,2%.log 2>&1

这个例子会从 C:\test.bat 输出结果,并将一个名为 test_YYYYMMDD-HHMMSS.log 的日志写入到 C:\log 目录

输出文件示例:c:\log\test_20181008-1121.log


6

你遇到的问题是,时间字符串可能包含一个空格(在10点之前)。 你可以用零替换它,但我推荐一种不依赖于本地设置的解决方案

for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I

它将为您提供以下内容(独立于区域设置!):
  20130802203023.304000+120 
( YYYYMMDDhhmmss.<fraction>+/-<timedifference to UTC>  )

从这里开始,将其格式化为您所需的格式非常容易。例如:

set datetime=%datetime:~0,8%-%datetime:~8,6%
20130802-203023

谢谢,这正是我在寻找的! - olivierr91

2
尝试像这样操作:

尝试像这样操作:

@echo off
set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
echo hour=%hour%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
echo min=%min%
set secs=%time:~6,2%
if "%secs:~0,1%" == " " set secs=0%secs:~1,1%
echo secs=%secs%

set year=%date:~-4%
echo year=%year%
set month=%date:~3,2%
if "%month:~0,1%" == " " set month=0%month:~1,1%
echo month=%month%
set day=%date:~0,2%
if "%day:~0,1%" == " " set day=0%day:~1,1%
echo day=%day%
Set MaDate=%day%/%month%/%year%
Set MyTime=%hour%:%min%:%secs%
echo %MaDate%
echo %MyTime%
set DateTimeFile=%year%_%month%_%day%_%hour%_%min%_%secs%.log
echo DateTimeFile=%DateTimeFile%
pause

我从foxidrive那里得到了另一种解决方案:

::From foxidrive
@echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime  ^| find "."') do set dt=%%a
set datestamp=%dt:~0,8%
set timestamp=%dt:~8,6%
set YYYY=%dt:~0,4%
set MM=%dt:~4,2%
set DD=%dt:~6,2%
set HH=%dt:~8,2%
set Min=%dt:~10,2%
set Sec=%dt:~12,2%
set stamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%
echo stamp: "%stamp%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
pause

1
也许对你来说最简单的解决方案是这个
set "dat=%date: =0%"
set "tim=%time: =0%"
"%PROGRAMFILES%\PostgreSQL\9.4\bin\vacuumdb.exe" --username postgres --verbose --analyze --all > E:\Logs\VacuumDB\%dat:~10,4%_%dat:~4,2%_%dat:~7,2%_%tim:~0,2%_%tim:~3,2%_%tim:~6,2%.log 2>&1

谢谢,它可以工作,但由于日期/时间格式在所有本地设置中并不相同,所以中间字符串函数并不总是提取正确的字符。Stephan的解决方案解决了这个问题。 - olivierr91
好的,你没有提到你遇到了本地问题。在你的示例代码之后,你说:“日志文件按预期生成为'2015_06_25__11_20_46.log'”... :/ - Aacini
是的,我知道,但我尝试了你的示例,输出的格式在我的电脑上是错误的(因为我的区域设置是 fr-CA),这突显出了区域设置问题。由于我只能选择一个答案,所以我选择了解决了区域设置问题的那个......对此很抱歉,但我仍然投了赞成票... - olivierr91
我认为这里有些混淆。我复制粘贴了你的代码,并添加了将空格替换为零的操作,因此所有子字符串位置与你之前发布的“日志文件按预期创建”时完全相同。然而,在你之前的评论中,你说“相同的子字符串”在我的环境中“输出错误的格式(因为我的语言环境是fr-CA)”?我不在乎声望分数,但是清楚这个细节对我很重要,因为英语不是我的母语。如果我误解了某些内容,请指出;否则,我只希望你说:“我的错误,对不起...”:/ - Aacini
我将您的解决方案粘贴到另一台计算机上,该计算机的区域设置与我用于提出原始问题的计算机不同,这就是发生错误格式输出的原因。另一位成员实际上预见了我没有提出的问题,并考虑到可能会出现的问题(我自己也发现了这一点)。所以,是的,您的解决方案确实解决了我最初发布的问题,毫无疑问。这件事没有人能受到责备。感谢您的答复和花时间帮助我... - olivierr91
我在另一台电脑上测试了你的解决方案,该电脑与引发原始问题的电脑有不同的行为。这一点违反了计算机支持论坛最基本的规则,但最糟糕的是,当你指出我的解决方案“输出错误格式”时,你没有给出任何建议。请理解我的观点:如果我忽略这种情况,那么唯一可能的结论就是你的电脑或者我的电脑以一种不可预测的方式失败了!如果你坚持认为“没有人能为此负责”,那么任何进一步的沟通都是无意义的... - Aacini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接