批量复制文件比较文件名中的日期与今天减去 X 天

Batch copy files comparing date in filename with today date minus X days

免责声明: 我需要比较 "last modified" 的日期,但 5 分钟前我收到了一个新要求,我需要与文件名上的日期,正如我在下面解释的那样。

假设我有 2 个文件夹:

FolderData 将接收文件名,如果不是日期,则文件名将相等,如:

  1. SYS_PURCHASES_20170617.xls
  2. SYS_PURCHASES_20170618.xls
  3. SYS_PURCHASES_20170619.xls

如果我今天 运行.bat 文件 我需要那个 SYS_PURCHASES_20170618.xls 复制到 FolderTemp。这必须通过从文件名 (20170618) 中获取 最后 8 个字符 并检查它是否与 TODAYDATE 匹配来完成 - 1.

批处理文件是否可行?如果可行,如何实现?

也接受 Windows PowerShell(6.1) 上的答案,如果它在之后也执行这些步骤:

  1. 当文件名中的日期 = 当前日期 - 1 时,将文件夹 1 中的所有文件复制到文件夹 2;
  2. 从文件夹 2 的所有文件中删除最后 9 位数字(将删除日期和取消下划线“_YYYYMMDD”)因此文件将是 SYS_PURCHASES.xls(需要考虑每个文件扩展名,因为会有 .xls, .xlsx 和 .txt);
  3. 将文件从文件夹 2 移动并替换到文件夹 3(使用简单的 move /y)- 我相信可以在执行第 2 步时执行此操作,不需要第三个文件夹。

只要脚本不是 运行 闰年的三月一日,FolderData 中最后一位对应 "yesterday" 的所有文件都将是

  • 复制到 FolderTemp,同时从文件名的最后 9 位中删除
  • 移动到 Folder3,同时从文件名的最后 9 位中删除

我的系统使用 DDMMYYYY 格式。交换前两个变量的值以将其设置为 MMDDYYYY。

setlocal enabledelayedexpansion


set day=%date:~,2%
set month=%date:~3,2%


set year=%date:~-4%
echo.%day%|findstr /r /b "0">nul&&set day=%day:~1%
echo.%month%|findstr /r /b "0">nul&&set month=%month:~1%
set /a day-=5
if %day% lss 1 (
    set /a day+=30
    set /a month-=1
    if !month!==2 (set /a day-=2
                   set /a leap=year%%4
                   if !leap!==0 set day+=1
    )
    for /l %%# in (1 2 7) do if %month%==%%# set /a day+=1
    for %%# in (8 10 12) do if %month%==%%# set /a day+=1
    if !month!==0 (
        set month=12
        set /a year-=1
    )
)
set day=0%day%
set month=0%month%

for %%# in (C:\FolderData\*) do (
    set name=%%~n#
    if "!name:~-8!"=="%year%%month:~-2%%day:~-2%" (
        copy "%%#" "C:\FolderTemp\!name:~,-9!%%~x#"
    )
)

如果我误解了什么请告诉我。

编辑:修改了脚本以说明返回多天。

使用以下 powershell 脚本 folder2 不是必需的, 您没有命名 folder3 - 所以请根据您的环境进行调整。

$Folder1 = "C:\Test17"
$Folder3 = "C:\Test17\Destination"

$YesterDay = (Get-Date).AddDays(-1).ToString('yyyyMMdd')

Get-ChildItem -Path $Folder1 -Filter "SYS_PURCHASES_$YesterDay.*"|Where{ !$_.PSisContainer}|
  Copy-Item -Destination {Join-Path $Folder3 (($($_.BaseName) -replace '_\d{8}$')+$_.Extension)} -whatif

以上脚本的原始输出仅插入换行符

PS C:\test17> ls
    Directory: C:\test17

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       06/20/2017     18:13                Destination
-a----       06/20/2017     18:01           1044 SO_44639321.ps1
-a----       06/20/2017     00:56             24 SYS_PURCHASES_20170617.xls
-a----       06/20/2017     00:56             24 SYS_PURCHASES_20170618.xls
-a----       06/20/2017     01:07             24 SYS_PURCHASES_20170619.txt
-a----       06/20/2017     00:56             24 SYS_PURCHASES_20170619.xls

PS C:\test17> .\SO_44639321.ps1
What if: Performing the operation "Copy File" on target 
"Item: C:\Test17\SYS_PURCHASES_20170619.txt Destination: C:\Test17\Destination\SYS_PURCHASES.txt".
What if: Performing the operation "Copy File" on target 
"Item: C:\Test17\SYS_PURCHASES_20170619.xls Destination: C:\Test17\Destination\SYS_PURCHASES.xls".
PS C:\test17> type .\SO_44639321.ps1

如果输出在您的系统上看起来正确,请删除最后一行末尾的 -whatif 参数。

组合 Batch/PowerShell 方法。

Powershell 用于日期计算,其余为纯批处理

@Echo Off&Setlocal EnableDelayedExpansion
Set "Folder1=C:\Test17"
Set "Folder3=C:\Test17\Destination"

For /f "usebackq delims=" %%A in (
  `Powershell -NonI -Nop -Com "(Get-Date).AddDays(-1).ToString('yyyyMMdd')"`
) Do Set YesterDay=%%A

For /F "Delims=" %%A in (
  'Dir /B/A-D "%Folder1%\*_%YesterDay%.*" '
) Do (
  Set "File=%%~nA"
  Set "File=!File:_%YesterDay%=!"
  Echo Copy "%%~fA" "%Folder3%\!File!%%~xA"
)

示例输出

> SO_44639321.cmd
Copy "C:\Test17\SYS_PURCHASES_20170619.txt" "C:\Test17\Destination\SYS_PURCHASES.txt"
Copy "C:\Test17\SYS_PURCHASES_20170619.xls" "C:\Test17\Destination\SYS_PURCHASES.xls"

如果输出看起来没问题,请删除副本前面的回显。