简体   繁体   English

Windows CMD 批处理时间戳与秒

[英]Windows CMD Batch Timestamp WITH SECONDS

I need to batch append a date modified timestamp to a filenames in Windows 10. I am almost there.我需要将日期修改时间戳批量附加到 Windows 10 中的文件名。我快到了。

The answer here was extremely helpful in getting me nearly to my objective. 这里的答案对让我接近目标非常有帮助。

The batch script below creates appends the file's date modified , but omits the seconds YYYYMMDDHHMM instead of YYYYMMDDHHMMSS (what I need).下面创建的批处理脚本会附加文件的date modified ,但省略秒YYYYMMDDHHMM而不是YYYYMMDDHHMMSS (我需要的)。

My computer's date format is YYYY-MM-DD , and time format hh:mm:ss .我电脑的日期格式是YYYY-MM-DD ,时间格式是hh:mm:ss

How can I achieve this?我怎样才能做到这一点?

@echo off
FOR /R "J:\PHP Member Reports\Test" %%Z IN (*.TRN) DO @( 
    FOR /F "Tokens=1-6 delims=:-\/. " %%A IN ("%%~tZ") DO @(
        ren "%%~dpnxZ" "%%~A%%~B%%~C%%~D%%~E%%~F_%%~nZ%%~xZ"
    )
)

It is necessary to use wmic – the Windows Management Instrumentation Command-line utility – to get last modification date of a file also with second.有必要使用wmic (Windows Management Instrumentation 命令行实用程序)来获取文件的最后修改日期,也可以使用秒。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "RenameError=0"
for /F "delims=" %%I in ('dir "J:\PHP Member Reports\Test\*.trn" /A-D-H /B /S 2^>nul') do call :ProcessFile "%%I"
if %RenameError% == 1 echo/ & pause
endlocal
goto :EOF

:ProcessFile
set "FileName=%~1"
set "FileName=%FileName:\=\\%"
set "FileDate="

rem Get last modification date of current file using Windows Management
rem Instrumentation Command-line utility (WMIC) which requires that each
rem backslash is escaped with a backslash.
for /F "usebackq tokens=2 delims==." %%T in (`%SystemRoot%\System32\wbem\wmic.exe DATAFILE where "name='%FileName%'" GET LastModified /VALUE 2^>nul`) do set "FileDate=%%T"
if defined FileDate goto RenameFile

rem The command line above fails if a comma exists anywhere in
rem file name with full path. Use in this case a different syntax.
if not defined FileDate for /F "usebackq tokens=2 delims==." %%T in (`%SystemRoot%\System32\wbem\wmic.exe DATAFILE where (name^="%FileName%"^) GET LastModified /VALUE 2^>nul`) do set "FileDate=%%T"
if defined FileDate goto RenameFile

rem The command line above fails again if there is a comma and additionally
rem also a closing parenthesis in file name with full path. To workaround
rem this issue copy the file with name WmicFile.tmp to the directory for
rem temporary files of which path does not contain usually , and ) at the
rem same time and get last modification date from this file before deleting
rem this temporary file.

copy "%~1" "%TEMP%\WmicFile.tmp" >nul
set "FileName=%TEMP%\WmicFile.tmp"
set "FileName=%FileName:\=\\%"
for /F "usebackq tokens=2 delims==." %%T in (`%SystemRoot%\System32\wbem\wmic.exe DATAFILE where "name='%FileName%'" GET LastModified /VALUE 2^>nul`) do set "FileDate=%%T"
del "%TEMP%\WmicFile.tmp"
if defined FileDate goto RenameFile

if %RenameError% == 1 echo/
echo ERROR: Failed to determine last modification date of file
echo        %1
set "RenameError=1"
goto :EOF

:RenameFile
set "FileName=%~n1"
rem Do nothing if current file name ends already with determined date/time.
if "%FileName:~-15%" == "_%FileDate%" goto :EOF
rem Rename the file with appending after an underscore the
rem last modification date and time in format YYYYMMDDhhmmss.
ren "%~1" "%~n1_%FileDate%%~x1" 2>nul
if not errorlevel 1 goto :EOF

if %RenameError% == 1 echo/
echo ERROR: Failed to rename the file
echo        %1
echo        to "%~n1_%FileDate%%~x1"
set "RenameError=1"
goto :EOF

It is no good idea to use file names retrieved by command FOR itself from a directory or directory tree on renaming, moving, deleting or copying files in directories searched by FOR .在重命名、移动、删除或复制FOR搜索的目录中的文件时,使用命令FOR本身从目录或目录树中检索的文件名不是一个好主意。 This can very easily result in omitting files or processing some files multiple times because of list of entries in a searched directory changes while FOR processes the directory entries.这很容易导致忽略文件或多次处理某些文件,因为在FOR处理目录条目时,搜索目录中的条目列表发生了变化。 It is strongly recommended to process a list of file names by FOR get completely before starting processing the files, especially on FAT drives (FAT16, FAT32, exFat) on which the file names are returned not sorted at all by the file system.强烈建议在开始处理文件之前通过FOR get 完全处理文件名列表,尤其是在文件名完全未按文件系统排序的 FAT 驱动器(FAT16、FAT32、exFat)上。

The command DIR is executed by FOR in a background command process started with cmd.exe /C which outputs to handle STDOUT only all non hidden files in specified directory and its subdirectories matching the wildcard pattern *.trn .命令DIRFOR在以cmd.exe /C启动的后台命令进程中执行,该进程仅输出以处理STDOUT指定目录及其与通配符模式匹配的子目录中的所有非隐藏文件*.trn This list of file names each with full path is captured by FOR .这个包含完整路径的文件名列表由FOR捕获。 Read also the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul .另请阅读有关使用命令重定向运算符的 Microsoft 文章,了解2>nul的说明。 The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.重定向运算符>必须在FOR命令行上使用脱字符^进行转义,以便在 Windows 命令解释器在执行命令FOR之前处理此命令行时解释为文字字符,该命令使用在后台启动的单独命令进程执行嵌入式dir命令行。

Each file name with full path is passed by FOR to subroutine ProcessFile enclosed in double quotes to work also for file names/paths containing a space or one of these characters &()[]{}^=;!'+,`~ .具有完整路径的每个文件名都由FOR传递给用双引号括起来的子例程ProcessFile也适用于包含空格或这些字符之一的文件名/路径&()[]{}^=;!'+,`~

The WMIC syntax requires that each file name is specified with full path and each backslash in file path is escaped with a backslash. WMIC语法要求使用完整路径指定每个文件名,并且使用反斜杠对文件路径中的每个反斜杠进行转义。 See also my answer on Find out if file is older than 4 hours in batch file .另请参阅我在Find out if file is older than 4 hours in batch file上的回答。

How to escape both comma and closing parenthesis in WHERE clause of WMIC?如何在 WMIC 的 WHERE 子句中同时转义逗号和右括号? explains that a full file name containing a comma , or a closing parenthesis ) is problematic.解释了包含逗号,右括号的完整文件)是有问题的。 The batch file is written to work around those problems.编写批处理文件是为了解决这些问题。 It can be expected that first executed FOR command line with WMIC is nearly always already successful on determining last modification date of file with second.可以预期,第一次使用WMIC执行的FOR命令行几乎总是已经成功地确定了文件的最后修改日期。

The batch file is written to output an error message if last modification date could not be determined for a file.如果无法确定文件的最后修改日期,则写入批处理文件以输出错误消息。

No rename is executed if a file name ends already with an underscore and the right last modification date/time.如果文件名已经以下划线和正确的最后修改日期/时间结尾,则不执行重命名。

It is verified by the batch file if rename operation was successful with displaying an error message on failed file rename.如果重命名操作成功并在文件重命名失败时显示错误消息,则由批处理文件验证。

Note: The batch file is not written to replace YYYYMMDDhhmmss at end of a file name by correct last modification date/time of this file.注意:批处理文件不会被写入文件名末尾的YYYYMMDDhhmmss替换为此文件的正确最后修改日期/时间。 This was not required in question.这不是问题所必需的。

The batch file halts execution at end with command PAUSE if any error occurred within subroutine ProcessFile .如果子例程ProcessFile中发生任何错误,批处理文件将在命令PAUSE结束时停止执行。 Otherwise the execution of the batch file ends without any user information output to STDOUT (console window).否则,批处理文件的执行结束,没有任何用户信息输出到STDOUT (控制台窗口)。

Please note that WMIC needs quite a long time to finish the operation.请注意, WMIC需要相当长的时间才能完成操作。 So on a large list of files this batch file can take several minutes to complete.因此,在大量文件中,此批处理文件可能需要几分钟才能完成。

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.要了解使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • call /?
  • copy /?
  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • rem /?
  • ren /?
  • set /?
  • setlocal /?
  • wmic /?
  • wmic datafile /?
  • wmic datafile get /?
  • wmic datafile get "last modified" /?
  • wmic datafile where /?

See also:也可以看看:

You could probably do this using RoboCopy which I understand provides a non locale dependent date and time.您可能可以使用RoboCopy来执行此操作,据我所知,它提供了不依赖于语言环境的日期和时间。 (Make necessary modifications only on lines 3 and 4 ) (仅对第3行和4行进行必要的修改)

@Echo Off

Set "filePath=J:\PHP Member Reports\Test"
Set "fileSpec=*.TRN"

Set "RCO=/S /L /XJ /R:0 /TS /FP /NS /NC /NP /NDL /NJH /NJS"
For /F "Tokens=1-6* Delims=/:    " %%A In (
    'RoboCopy "%filePath%" Null "%fileSpec%" %RCO%'
) Do If Not Exist "%%A%%B%%C%%D%%E%%F%%~xG" (
    Echo=Ren "%%G" "%%A%%B%%C%%D%%E%%F%%~xG")
Pause

Where Delims=/:<tab><space> or / : Tab Delims=/:<tab><space>/ : Tab                                           

The script currently only Echo es the Ren ame commands;该脚本目前仅Echo es Ren名称命令; remove Echo= from line 10 and Pause from the last line if you are happy with the results.如果您对结果感到满意,请从第10行删除Echo=并从最后一行删除Pause

Also please note that this is to answer your question only.另请注意,这只是为了回答您的问题。 Any problems arising from renaming your files to also match your file specification, or already existing files will need to be tackled separately.重命名文件以匹配文件规范或现有文件引起的任何问题都需要单独解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM