简体   繁体   English

批处理:复制上次修改时间为 15 分钟前的文件

[英]Batch: Copy files which last modification were 15 minutes before

I have a folder where files are automatically created and I need every 5 minutes to copy the new files (that is, the files whose last modification was in the last 5 minutes).我有一个自动创建文件的文件夹,我需要每 5 分钟复制一次新文件(即最后一次修改是在最后 5 分钟内的文件)。

 :loop
for %a in (C:\test\*) do (
 set FileDate=%~ta
)
 timeout /t 300
 goto loop

That's the way I have found to get date of file but I don't know how to compare and get the current date less 5 minutes.这就是我发现获取文件日期的方式,但我不知道如何比较并获得当前日期少于 5 分钟。

(The copy command is not necessary, because is via SSH and this problem is resolved). (复制命令不是必需的,因为是通过 SSH 并且此问题已解决)。

In batch date time calculations are a very tedious task.在批处理中,日期时间计算是一项非常繁琐的任务。

I suggest to use PowerShell (at least as a tool)我建议使用 PowerShell(至少作为一种工具)

To get the files created in the current directory in the last 5 minutes.获取最近 5 分钟在当前目录中创建的文件。
This powershell command will output a dir -like listing:此 powershell 命令将输出类似dir的列表:

Get-ChildItem -Path 'X:\path'|Where-Object {((Get-Date) - $_.LastWriteTime).TotalMinutes -le 5}

To restrict this to only the FullName you can append the pipe要将其限制为仅 FullName,您可以附加管道

| Select-Object -ExpandProperty FullName

or simply enclose the command in parentheses and append (...).FullName或者简单地将命令括在括号中并附加 (...).FullName

(Get-ChildItem -Path 'X:\path'|Where-Object {((Get-Date) - $_.LastWriteTime).TotalMinutes -le 5}).FullName

Wrapped in a batch包裹成一批

:: Q:\Test\2018\11\08\SO_53206386.cmd
@Echo off
for /f "usebackq delims=" %%A in (`
  powershell -Nop -C "(Get-ChildItem -Path 'X:\path' -File |Where-Object {((Get-Date) - $_.LastWriteTime).TotalMinutes -le 15}).FullName"
`) Do Echo %%A

Sample output of this batch (listing itself)此批次的示例输出(列表本身)

> SO_53206386.cmd
Q:\Test\2018\11\08\SO_53206386.cmd

The -File parameter requires PowerShell v3+ but can be replaced with another piped command -File参数需要 PowerShell v3+,但可以用另一个管道命令替换

| Where-Object {!($PSISContainer)}

filtering out folders.过滤掉文件夹。 (The opposite is -Directory or no ! for not) (相反的是-Directory or no ! for not)

@Echo off
for /f "usebackq delims=" %%A in (`
  powershell -Nop -C "(Get-ChildItem -Path 'X:\path' | Where-Object {!($PSISContainer)}| Where-Object {((Get-Date) - $_.LastWriteTime).TotalMinutes -le 15}).FullName"
`) Do Echo %%A

Here is a completely different solution resulting in most likely the same behavior with the advantage that the last modification date of a file does not really matter.这是一个完全不同的解决方案,很可能导致相同的行为,其优点是文件的最后修改日期并不重要。 So if a file is copied into the observed folder, it is also processed even if its last modification time is not within the last X minutes.因此,如果将文件复制到观察文件夹中,即使其最后修改时间不在最后X分钟内,也会对其进行处理。 It uses the archive file attribute set by Windows automatically each time a file is created in a folder or the file is modified by a process.每次在文件夹中创建文件或文件被进程修改时,它都会自动使用 Windows 设置的存档文件属性。

@echo off
set "Folder=C:\test"
:loop
for /F "eol=| delims=" %%I in ('dir "%Folder%\*" /AA-D-H /B /ON 2^>nul') do (
    %SystemRoot%\System32\attrib.exe -a "%Folder%\%%I"
    echo Copy the file "%Folder%\%%I"
)
%SystemRoot%\System32\timeout.exe /T 300
goto loop

The command FOR executes the following command line in a separate command process started with cmd.exe /C in background.命令FOR在后台以cmd.exe /C启动的单独命令进程中执行以下命令行。

dir "C:\test\*" /AA-D-H /B /ON 2>nul

The command DIR outputs命令DIR输出

  • in bare format only file name and file extension because of /B由于/B ,仅以裸格式显示文件名和文件扩展名
  • only non-hidden files with archive attribute set because of /AA-DH由于/AA-DH ,仅具有归档属性集的非隐藏文件
  • ordered by file name because of /ON (not really needed)由于/ON按文件名排序(实际上不需要)
  • found in directory C:\test matching wildcard pattern * .在目录C:\test中找到匹配通配符模式*

The error message output by DIR on not finding any directory entry matching these requirements is suppressed by redirecting it from handle STDERR to device NUL . DIR在找不到任何符合这些要求的目录条目时输出的错误消息通过将其从句柄STDERR重定向到设备NUL来抑制。

Read 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命令行。

This output of DIR in separate command process is captured by FOR and processed line by line.这个DIR在单独的命令过程中的输出被FOR捕获并逐行处理。

Empty lines are always skipped by FOR which do not occur here. FOR总是跳过空行,这里不会出现。

Lines (file names) starting with a semicolon are also skipped by default by FOR . FOR也默认跳过以分号开头的行(文件名)。 This behavior is disabled by changing with eol=|通过使用eol=|更改禁用此行为the end of line character from default ;默认的行尾字符; to vertical bar which no file name can have anywhere.到任何文件名都不能有的竖线。

FOR splits up by default the line in substrings (tokens) using space/tab as delimiters and assigns just first space/tab delimited string to specified loop variable I . FOR默认使用空格/制表符作为分隔符拆分子字符串(标记)中的行,并将第一个空格/制表符分隔的字符串分配给指定的循环变量I This behavior is not wanted here as file names can contain one or more spaces.此处不需要此行为,因为文件名可以包含一个或多个空格。 For that reason delims= is used to specify an empty list of delimiters which disables the line splitting behavior.出于这个原因, delims=用于指定一个空的分隔符列表,该列表禁用行拆分行为。

So assigned to loop variable I is the file name with file extension as output by DIR without path.因此,分配给循环变量I的是带有文件扩展名的文件名,由DIR输出,没有路径。

The command ATTRIB is used to remove the archive attribute from current file for next iteration of the FOR loop.命令ATTRIB用于从当前文件中删除归档属性,以用于 FOR循环的下一次迭代。 Then the file can be copied to a different location or processed otherwise not modifying its content.然后可以将文件复制到不同的位置或进行处理,否则不会修改其内容。

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.要了解使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • attrib /?
  • dir /?
  • echo /?
  • for /?
  • goto /?
  • timeout /?

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

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