复制多个文件的最新版本

问题描述 投票:0回答:2

编辑:谢谢您的评论。我最初的计划是下载所有文件并删除不必要的文件,但后来我认为只下载我需要的文件要聪明得多。我正在更改这方面的标题。

我正在寻找一个批处理脚本来管理文件的最新版本。

文件名是自动生成的,并且这些文件通常有多个版本。我正在寻找一种获取最新内容的方法。

文件名遵循相同的模式:

[ID][周][版本]_[其他文本]

示例:

  • 12345_2440_01_2_11.csv
  • 12345_2440_02_2_11.csv
  • 12345_2440_03_2_11.csv

@Compo,其中,12345 是[ID],2440 是[周],01 是[版本],2 和11 是[其他文本]。最新的版本是最高版本的。在这种情况下 03.

  • 34567_2440_01_2_11.csv

  • 34567_2440_02_2_11.csv

  • 34567_2440_03_2_11.csv

  • 34567_2440_04_2_11.csv

  • 34567_2440_05_2_11.csv

今天,我使用一个非常简单的脚本,因为我不知道每个文件有多少版本 - 1 或 20,然后手动删除旧版本。

copy \\server\folder\subfolder\12345_2440* C:\folder\
copy \\server\folder\subfolder\34567_2440* C:\folder\
set /p=

我正在寻找一种更聪明的方法来仅复制我需要的内容。 在上面的例子中,我想复制 12345_2440_03_2_11.csv 和 34567_2440_05_2_11.csv,而不是全部 8 个文件。

有没有简单的脚本可以做到这一点?

提前谢谢您! 干杯!

batch-file command-prompt
2个回答
0
投票
@ECHO OFF
SETLOCAL
rem The following settings for the directories are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"
SET "destdir=u:\your results"

SET "ID=:"
SET "Week=:"
FOR /f "tokens=1,2*delims=_" %%g IN (
 'dir /b /a-d /o-n "%sourcedir%\*_*_*_*_*.csv" '
 ) DO (
  CALL :doimoveit %%g %%h
  IF DEFINED moveit ECHO COPY "%sourcedir%\%%g_%%h_%%i" "%destdir%\"
)

GOTO :EOF

::
:: Set moveit to a value if %1 or %2 are different from their prior values
::
:doimoveit

: default - don't move it
SET "moveit="
IF /i "%1" NEQ "%ID%" GOTO moveme
IF /i "%2" NEQ "%Week%" GOTO moveme
GOTO :eof
:moveme
SET "moveit=Y"
SET "ID=%1" 
SET "Week=%2" 
GOTO :eof

执行源目录的

dir
列表,使用文件名掩码
*_*_*_*_*.csv
来查找符合您的模式的所有文件。
a-d
排除目录
/o-n
按名称的相反顺序排序(以便所需的要复制的文件出现在具有相同 ID 和周数的任何其他名称之前)。
/b
提供基础数据; IE。仅名字。

请参阅提示中的

FOR /?
或 SO 上的数千个示例,了解有关
delims
tokens
选项如何工作的信息。本质上,由于
delims
设置为
_
,那么
dir
传递的名称将是
tokenised
,第一个标记分配给
%%g
,第二个标记分配给
%%h
,名称的其余部分分配给
%%i

doimoveit
子例程接受文件的ID和周,并将这些元素与遇到的先前版本进行比较(由于
:
不能出现在文件名中,因此将
ID
Week
设置为
:
最初可确保复制遇到的第一个名字)

如果这两个元素是先前名称的重复,则从

moveit
返回时,call 保持设置为
nothing
。如果没有,我们就有了新的 ID 或周,因此将
moveit
设置为 something 并记录新的 ID 和周。

使用布尔值

copy
已被
echo
进行验证。删除
echo
关键字以实际执行
copy


0
投票

下面提供的所有三种解决方案都要求具有相同标识符和周的所有文件的版本位数相同。在示例文件名列表中,所有文件都有两位数字的版本号。

如果源文件夹路径、目标文件夹路径以及任何文件名都不包含一个或多个

!
,可以使用以下批处理文件。

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "SourceFolder=\\server\folder\subfolder"
set "DestinationFolder=C:\folder"
md "!DestinationFolder!" 2>nul
if not exist "!DestinationFolder!\" echo ERROR: Missing folder: "!DestinationFolder!"& exit /B 1
set "ID_Week="
for /F "delims=" %%G in ('dir "!SourceFolder!\*_*_*_*.csv" /A-D /B /O-N 2^>nul') do for /F "tokens=1,2 delims=_" %%I in ("%%G") do if not "!ID_Week!" == "%%I_%%J" set "ID_Week=%%I_%%J" & copy "!SourceFolder!\%%G" "!DestinationFolder!\" 1>nul
endlocal

如果源或目标文件夹路径包含一个或多个

!
但文件名不带感叹号,则可以使用以下批处理文件。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=\\server\folder\subfolder"
set "DestinationFolder=C:\folder"
md "%DestinationFolder%" 2>nul
if not exist "%DestinationFolder%\" echo ERROR: Missing folder: "%DestinationFolder%"& exit /B 1
setlocal EnableDelayedExpansion
set "ID_Week="
for /F "delims=" %%G in ('dir "!SourceFolder!\*_*_*_*.csv" /A-D /B /O-N 2^>nul') do for /F "tokens=1,2 delims=_" %%I in ("%%G") do if not "!ID_Week!" == "%%I_%%J" set "ID_Week=%%I_%%J" & copy "!SourceFolder!\%%G" "!DestinationFolder!\" 1>nul
endlocal
endlocal

以下批处理文件是最慢的,但即使文件名在其他文本部分包含一个或多个感叹号也可以工作。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=\\server\folder\subfolder"
set "DestinationFolder=C:\folder"
md "%DestinationFolder%" 2>nul
if not exist "%DestinationFolder%\" echo ERROR: Missing folder: "%DestinationFolder%"& exit /B 1
set "ID_Week="
for /F "delims=" %%G in ('dir "%SourceFolder%\*_*_*_*.csv" /A-D /B /O-N 2^>nul') do for /F "tokens=1,2 delims=_" %%I in ("%%G") do (
    setlocal EnableDelayedExpansion
    if not "!ID_Week!" == "%%I_%%J" (
        endlocal
        set "ID_Week=%%I_%%J"
        copy "%SourceFolder%\%%G" "%DestinationFolder%\" 1>nul
    ) else endlocal
)
endlocal

主要技巧是在源文件夹中获取按名称反向排序的匹配 CSV 文件名列表,如果标识符和周部分与当前存储在环境变量中的标识符和周相比发生变化,则始终复制列表中的第一个文件

ID_Week
.

要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • copy /?
  • dir /?
  • echo /?
  • endlocal /?
  • exit /?
  • for /?
  • if /?
  • md /?
  • set /?
  • setlocal /?

阅读有关 使用命令重定向运算符的 Microsoft 文档,了解

1>nul
2>nul
的说明。当 Windows 命令解释器在执行命令
FOR
(执行嵌入的
>
命令行)之前处理此命令行时,重定向运算符 ^ 必须在 FOR 命令行上使用脱字符号
dir
进行转义,以便将其解释为文字字符使用在后台启动的单独命令进程,并附加
%ComSpec% /c
'
内的命令行。

使用 Windows 批处理文件的单行多个命令解释了所有代码示例中使用的无条件命令运算符

&
。在命令
&
之后,
echo
没有剩余空格,否则命令
echo
也会将此空格输出为尾随空格。

© www.soinside.com 2019 - 2024. All rights reserved.