【问题标题】:Windows CMD/BATCH Keep newest date stamped fileWindows CMD/BATCH 保留最新的日期戳文件
【发布时间】:2019-02-14 00:43:54
【问题描述】:

我有一些文件要整理并保留最新的文件。 我不能通过修改或创建的文件属性日期来做到这一点,我可以做到这一点。

这是文件的命名约定。 文件ABC_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*
)  

【问题讨论】:

  • 您提供的文件已经按日期顺序排列,最新的在前,并且给定您分配给它们的名称按字母顺序排序,这意味着最新的文件将始终排在最前面或最后,具体取决于排序顺序。
  • 我并不是真的要订购或分类它们。我只想删除除最新文件之外的所有文件。我解析了日期,这样我就可以尝试做一些数学运算来获得最大的日期,然后使用某种逻辑来删除比最新日期更旧的任何内容。
  • 您不能对文本字符串进行数学运算,您可以做的是在公共分隔符处拆分名称,对日期部分的文件进行排序,然后以排序或反向排序的顺序删除它们,除了一个!
  • 这里有很多现有的帖子应该可以让你开始。试试这些,例如:stackoverflow.com/q/54657806/62576stackoverflow.com/q/44057048/62576
  • FileABC 部分是否可以单独包含字符 _

标签: windows powershell batch-file cmd


【解决方案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

【讨论】:

    【解决方案2】:

    如果您不关心文件日期而只关心文件名中的日期,您可以执行以下操作,因为 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】:

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

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

      重要!

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

      要了解有关我们使用的函数的更多信息,请从cmd.exe 运行以下命令

      • for /?
      • dir /?

      【讨论】:

        【解决方案4】:

        作为一个附加选项,以防文件名前缀在整个过程中发生变化并且只有 _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 行只是定义和取消定义我们将使用的变量。
        • 56 行是单行,为了便于阅读,分成两行。这将使用文件基名的最后八个字符将变量设置为完整文件名的值。
        • 包含7 行以退出脚本,以防在2 行设置的目录中找不到基本名称以下划线后跟八个字符结尾的.txt 文件。
        • 8 行是这里的特殊行,它按字母顺序输出每个变量和对应的值。输出设置为一个变量,该变量会覆盖自身,直到循环结束。这意味着最新的文件,按字母顺序排列的最后一个,与以最新日期命名的文件的值一起保存。
        • 910 行再次将单行拆分为两行以提高可读性。这将再次循环目录中的所有匹配文件,并使用Find 命令排除输出与变量中保存的文件匹配的文件作为具有最新日期的文件。使用Del 命令简单地删除每个文件输出。

        请注意,此脚本假定您每个日期只有一个文件,因为您只声明这些文件每周生成一次。

        【讨论】:

        • 谢谢你的成功,我也感谢你的解释。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-04
        • 1970-01-01
        • 2021-02-27
        • 2021-04-10
        • 2019-06-24
        相关资源
        最近更新 更多