CMD行BATCH文件 - 找到最近的文件“LIKE”并重命名它

时间:2016-01-02 01:30:37

标签: windows csv batch-file cmd

我得到的东西在一段时间内给了我一些问题。我有一份.csv个文件的报告列表。他们的组织方式是:

Call Details Report_1448937644342.csv
Call Details Report_1449662976507.csv
Call Details Report_1450293169999.csv
Initial Call Pricing By Archive Report_1448937621469.csv
Initial Call Pricing By Archive Report_1449662916869.csv
Initial Call Pricing By Archive Report_1450293146194.csv
Location Detail Report_1448937658179.csv
Location Detail Report_1449662949955.csv
Location Detail Report_1450293201330.csv
Location Summary Report_1448937672801.csv
Location Summary Report_1449662994508.csv
Location Summary Report_1450293231606.csv
StartStop (1).csv
StartStop (2).csv
StartStop (3).csv
StartStop.csv
Sensor (1).csv
Sensor (2).csv
Sensor (3).csv

所以我需要的是我可以将每个报告的最新报告复制到不同的目录,同时在没有空格或数字的情况下重命名它(CallDetailsReport,IntialCallPricingByArchiveReport等)。因此,如果我现在运行批处理文件,它将采用该文件目录,查找每个报告的最新内容,复制并将其重命名为另一个目录。

我曾尝试使用FOR命令,但运气很少,我遇到的最大问题是_之后的数字变化很大,但总是更大。我也想过,也许我可以通过最新的文件来缩小范围,但总结不同的结局会让我感到困惑。我希望你们能帮忙。

到目前为止,我得到了这个列表,但不会将其缩小到最近。

FOR %%G IN (Report1*.csv ) do @echo %%G

3 个答案:

答案 0 :(得分:0)

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
FOR /f "tokens=1*delims= " %%a IN (
  'dir /b /a-d /o-d "%sourcedir%\*.csv" '
  ) DO (
 IF "%%b" neq "" IF NOT EXIST "%destdir%\%%a" COPY "%sourcedir%\%%a %%b" "%destdir%\%%a" >nul
)

GOTO :EOF

您需要更改sourcedirdestdir的设置以适合您的具体情况。

以基本形式读取源目录,不带目录名,并按反向日期顺序读取,以便首先显示与掩码匹配的最新文件。使用空格作为分隔符将文件名拆分为两个。如果第二部分不为空(即空间存在),则测试目标目录中是否存在文件thefirstpart,如果不存在则执行复制 - 因此将从第一部分复制(最新)找到文件但不会被覆盖。

根据您的实际要求进行的调整将在您的法庭上进行。

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
FOR /f "tokens=1*delims=_" %%a IN (
  'dir /b /a-d /o-d "%sourcedir%\*.csv" '
  ) DO (
 IF "%%b" equ "" (
  FOR /f "tokens=1*delims= " %%j IN ("%%a") DO (
   IF "%%k" neq "" IF NOT EXIST "%destdir%\%%j" COPY "%sourcedir%\%%a" "%destdir%\%%j" 
  )
 ) ELSE (
  IF NOT EXIST "%destdir%\%%a" COPY "%sourcedir%\%%a_%%b" "%destdir%\%%a" 
 )
)

GOTO :EOF

修改以适合真实的文件名。

答案 1 :(得分:0)

原始答案(基于original question

假设最大的数字表示最近的项目,则以下批处理脚本会执行您要查找的内容:

@echo off
setlocal EnableExtensions EnableDelayedExpansion

rem Set up source and destination directories here:
set "SOURCE=D:\source"
set "DESTIN=D:\destin"

for /F "tokens=1,2,3,4 delims=._ " %%I in ('
    2^> nul dir /B /A:-D "%SOURCE%\*.csv" ^| ^
    findstr /I /R /C:"^Report[0-9][0-9]* Number_[0-9][0-9]*.csv$"
') do (
    set "REPORT=%%I"
    set "REPORT=0000000!REPORT:*Report=!"
    set "NUMBER=0000000%%K"
    set "ITEM-!REPORT:~-8!=%%I.%%L"
    set "ITEMS-!REPORT:~-8!-!NUMBER:~-8!=%%I %%J_%%K.%%L"
)
for /F "tokens=2,3 delims=-=" %%I in ('
    2^> nul set ITEM-
') do (
    for /F "tokens=2 delims==" %%X in ('
        2^> nul set ITEMS-%%I-
    ') do (
        set "RECENT=%%X"
    )
    > nul copy /Y /B "%SOURCE%\!RECENT!" "%DESTIN%\%%J"
)
endlocal
exit /B

这种方法基本上构建了类似于数组的变量ITEM-ITEMS-,它们用文件名中的数字填充前导零,由8位数组成,然后使用set进行排序按字母顺序排列项目并检索最新项目。由于填充,字母排序的结果与字母数字排序的顺序相同。

这两个变量都是在第一个for /F循环中设置的,它使用dir /B /A:-D "*.csv" | findstr /I /R /C:"^Report[0-9][0-9]* Number_[0-9][0-9]*.csv$"枚举所有适用的项目。 findstr用于过滤文件,因为dir无法在同一等级的详细信息中进行过滤。变量名称包含用于正确排序的零填充数字。变量值是原始文件名(ITEMS-)和新文件名(ITEM-)。

第二个for /F循环解析set ITEM-的输出,该输出遍历单词Report之后的所有第一个数字。这个循环嵌套另一个循环,遍历set ITEMS-的输出,该输出将两个数字都保存在文件名中。内部循环将当前项存储在变量RECENT中,并且每次都会覆盖其值。由于排序顺序,最大数量,因此最新项目存储在RECENT中。然后外部循环实际上复制相关文件。

依靠您提供的示例文件,这两个数组将保存以下数据:

ITEM-(已排序):

ITEM-00000001=Report1.csv
ITEM-00000002=Report2.csv
ITEM-00000003=Report3.csv

ITEMS-(已排序):

ITEMS-00000001-00000123=Report1 Number_123.csv
ITEMS-00000001-00000126=Report1 Number_126.csv
ITEMS-00000001-00000133=Report1 Number_133.csv
ITEMS-00000002-00000123=Report2 Number_123.csv
ITEMS-00000002-00000126=Report2 Number_126.csv
ITEMS-00000002-00000133=Report2 Number_133.csv
ITEMS-00000003-00000123=Report3 Number_123.csv
ITEMS-00000003-00000126=Report3 Number_126.csv
ITEMS-00000003-00000133=Report3 Number_133.csv

更新的答案(基于revised question

在问题original requirements中密集更改了most recent revision后,我对该脚本进行了大量修改,并提出了以下两个脚本,每个脚本都处理了{{1}的某个名称模式报告文件。两个脚本都依赖于一个临时文件,该文件用于使用*.csv命令进行适当的排序,以获得具有最大数字的正确项目:

  1. 此脚本处理所有报告文件,其文件名中包含报告名称,下划线sort和索引号。

    _

    相关的临时文件包含以下未排序的数据,具体取决于您的示例文件:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem Set up source and destination directories here:
    set "SOURCE=D:\source"
    set "DESTIN=D:\destin"
    
    > "%~dpn0.tmp" (
        for /F "tokens=1,2 delims=_" %%I in ('
            2^> nul dir /B /A:-D "%SOURCE%\*.csv" ^| ^
            findstr /I /R /C:"^[^_][^_]*_[0-9][0-9]*.csv$"
        ') do (
            set "REPORT=%%I"
            set "NUMBER=00000000000000000000000%%~nJ"
            setlocal EnableDelayedExpansion
            echo(!REPORT!^|!NUMBER:~-24!^|!REPORT!_%%J
            endlocal
        )
    )
    set "FORMER="
    < "%~dpn0.tmp" (
        for /F "tokens=1,3 delims=|" %%I in ('
            sort /R
        ') do (
            set "REPORT=%%I"
            set "ORNAME=%%J"
            setlocal EnableDelayedExpansion
            if /I not "!REPORT!"=="!FORMER!" (
                > nul copy /Y /B "%SOURCE%\!ORNAME!" "%DESTIN%\!REPORT: =!%%~xJ"
            )
            endlocal
            set "FORMER=%%I"
        )
    )
    del /Q "%~dpn0.tmp"
    endlocal
    exit /B
    

    然后使用Call Details Report|000000000001448937644342|Call Details Report_1448937644342.csv Call Details Report|000000000001449662976507|Call Details Report_1449662976507.csv Call Details Report|000000000001450293169999|Call Details Report_1450293169999.csv Initial Call Pricing By Archive Report|000000000001448937621469|Initial Call Pricing By Archive Report_1448937621469.csv Initial Call Pricing By Archive Report|000000000001449662916869|Initial Call Pricing By Archive Report_1449662916869.csv Initial Call Pricing By Archive Report|000000000001450293146194|Initial Call Pricing By Archive Report_1450293146194.csv Location Detail Report|000000000001448937658179|Location Detail Report_1448937658179.csv Location Detail Report|000000000001449662949955|Location Detail Report_1449662949955.csv Location Detail Report|000000000001450293201330|Location Detail Report_1450293201330.csv Location Summary Report|000000000001448937672801|Location Summary Report_1448937672801.csv Location Summary Report|000000000001449662994508|Location Summary Report_1449662994508.csv Location Summary Report|000000000001450293231606|Location Summary Report_1450293231606.csv 对数据进行排序,其中sort /R定义反向排序顺序。第一个/R - 分隔字段包含报告名称,第二个字段包含零填充索引号,第三个字段包含原始文件名。只有这样的行用于复制,其中包含与上一行不同的报告名称。

  2. 此脚本处理文件名中包含报告名称, SPACE |,索引号和(的所有报告文件。它甚至处理不包含索引号但只包含文件名中的报告名的文件,它们被视为索引为)

    0

    相关的临时文件包含以下未排序的数据,具体取决于您的示例文件:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem Set up source and destination directories here:
    set "SOURCE=D:\source"
    set "DESTIN=D:\destin"
    
    > "%~dpn0.tmp" (
        for /F "tokens=1,2,3 delims=()" %%I in ('
            2^> nul dir /B /A:-D "%SOURCE%\*.csv" ^| ^
            findstr /I /R /C:"^[^()]*[^()0-9].csv$" /C:"^[^()][^()]* ([0-9][0-9]*).csv$"
        ') do (
            if "%%J"=="" (
                set "REPORT=%%~nI"
                set "NUMBER=000000000000000000000000"
                setlocal EnableDelayedExpansion
                echo(!REPORT!^|!NUMBER:~-24!^|!REPORT!%%~xI
                endlocal
            ) else (
                set "REPORT=%%I"
                set "NUMBER=00000000000000000000000%%J"
                setlocal EnableDelayedExpansion
                echo(!REPORT:~,-1!^|!NUMBER:~-24!^|!REPORT!^(%%J^)%%K
                endlocal
            )
        )
    )
    set "FORMER="
    < "%~dpn0.tmp" (
        for /F "tokens=1,3 delims=|" %%I in ('
            sort /R
        ') do (
            set "REPORT=%%I"
            set "ORNAME=%%J"
            setlocal EnableDelayedExpansion
            if /I not "!REPORT!"=="!FORMER!" (
                > nul copy /Y /B "%SOURCE%\!ORNAME!" "%DESTIN%\!REPORT: =!%%~xJ"
            )
            endlocal
            set "FORMER=%%I"
        )
    )
    del /Q "%~dpn0.tmp"
    endlocal
    exit /B
    

    排序技术与其他脚本相同。

  3. 为了获得所需的所有报告文件,您需要执行这两个脚本。

答案 2 :(得分:0)

试试这个:

@echo off

set max=0
for /f "tokens=2 delims=_." %%n in ('dir /b Report1*.csv') do (
    if %%n GTR !max! set max=%%n
)
copy "Report1 Number_%max%.csv" otherdir\Report1.csv