Windows CMD / BATCH保留最新的日期戳文件

时间:2019-02-14 00:43:54

标签: windows powershell batch-file cmd

我想对一些文件进行排序并保留最新文件。 我不能通过修改或创建日期的文件属性来做到这一点,这没问题。

这是文件的命名约定。 FileABC_YYYYMMDD.txt

  • FileABC_20190201.txt
  • FileABC_20190125.txt
  • FileABC_20190118.txt
  • FileABC_20190111.txt
  • FileABC_20190104.txt

您可以看到日期戳位于文件名本身中。这些文件每周生成一次。因此,我希望通过它们进行批处理文件循环,并删除除当前日期以外的所有文件。我确实在寻找如何做到最好的方法,但没有找到太多,因此我需要想法。我更喜欢纯cmd解决方案,但我也欢迎使用Powershell解决方案。


我自己想做的是用...解析日期。

@echo off
setlocal enabledelayedexpansion
for /f "tokens=* delims= " %%G IN ('dir/b /a-d "C:\Users\thomas.maus\Documents\Tom\dev\Test Batch Files\dev\sortbyFileDateName\FileABC_*.txt"') do (

            set fileName=%%G 
            Set theDate=!fileName:~8,8!
            echo !theDate!


)

然后我想以某种方式从循环结果中获取那些日期,并执行

if "%theDate%" GEQ "*****not sure what to put here*****" (
    del *all the old files, also not sure what to put here*
)  

4 个答案:

答案 0 :(得分:1)

怎么样?

@echo off
for /f "skip=1" %%i in ('dir /o-n /b *.txt') do del %%i

如果您只想先测试它(看看它会删除什么),请执行以下操作:

@echo off
for /f "skip=1" %%i in ('dir /o-n /b *.txt') do echo %%i

答案 1 :(得分:1)

我们只浏览文件,按日期降序排列,然后跳过第一个文件,现在是最新文件:

@for /f "skip=1" %%a in ('dir /b /o-d *.txt') do @echo @del %%a

重要!

此示例仅将echo删除命令作为一种安全措施,因此您不会删除不应拥有的文件。要执行实际的删除,请从行中删除@echo

要了解有关我们使用的功能的更多信息,请从cmd.exe

运行以下命令
  • for /?
  • dir /?

答案 2 :(得分:1)

如果您不关心文件日期,而只关心文件名中的日期,则可以执行以下操作,因为部分FileABC始终相同并且不包含任何_独自:

pushd "C:\Users\thomas.maus\Documents\Tom\dev\Test Batch Files\dev\sortbyFileDateName" && (
    for /F "skip=1 delims= eol=|" %%F in ('
        dir /B /A:-D "FileABC_????????.txt" ^
            ^| sort /R
    ') do (
        del "%%F"
    )
    popd
)

尽管sort /R可以进行字母排序,但是由于您选择了日期格式,因此可以使用此功能,这可以确保字母顺序等于字母数字顺序。

答案 3 :(得分:0)

作为一个附加选项,以防万一文件名前缀始终更改并且仅_YYYYMMDD.txt保持不变,您仍然可以使用该日期执行任务,因为该日期已经可以按字母顺序排序。

这是一个例子:

@Echo Off
Set "SrcDir=%UserProfile%\Documents\Tom\dev\Test Batch Files\dev\sortbyFileDateName"
For /F "Delims==" %%A In ('Set $ 2^>Nul') Do Set "%%A="
Set "_="
For /F Delims^=^ EOL^= %%A In ('Where "%SrcDir%":*_????????.txt 2^>Nul'
) Do Set "_=%%~nA" & Call Set "$%%_:~-8%%=%%A"
If Not Defined _ Exit /B
For /F "Tokens=1* Delims==" %%A In ('Set $ 2^>Nul') Do Set "_=%%B"
For /F Delims^=^ EOL^= %%A In ('Where "%SrcDir%":*_????????.txt^|Find /V "%_%"'
) Do Del /A /F "%%A"

这利用了Set命令将按字母顺序输出变量的事实。

  • 24行仅定义和取消定义我们将使用的变量。
  • 5行和6行是一条单行,分为两行,以提高可读性。这将使用文件基名的最后八个字符将变量设置为完整文件名的值。
  • 包括行7可以退出脚本,以防万一在行.txt设置的目录中找不到以下划线后跟八个字符的基本名称的2文件。
  • 8行是这里的特殊行,它按字母顺序输出每个变量和相应的值。输出设置为一个变量,该变量将覆盖自身直到循环结束。这意味着,最新文件按字母顺序最后一个保存,并带有以最新日期命名的文件的值。
  • 9行和10行又是一条单行,分为两行以提高可读性。这会再次循环遍历目录中的所有匹配文件,并使用Find命令排除将与变量中保存的文件匹配的文件作为具有最新日期的文件输出。只需使用Del命令删除每个文件输出即可。

请注意,此脚本假定每个日期只有一个文件,因为您只说过文件是每周生成的。