CMD / BAT会修改所有文件名的日期并附加到其文件名

时间:2019-05-17 22:36:12

标签: windows batch-file cmd

我在使用此脚本时遇到麻烦。我将在代码块下面进行解释。

@Echo off
pushd "\\server\folder"
SETLOCAL EnableDelayedExpansion

@FOR /F "TOKENS=2" %%A IN ('WHERE /T "testfiles*.*"') DO @(
set fdate123=%%A
echo !fdate123:~5,9!0!fdate123:~0,1!!fdate123:~2,2!
call StringLen !fdate123!
)

pause

:StringLen
Setlocal EnableDelayedExpansion
:: strLen String [RtnVar]
::             -- String  The string to be measured, surround in quotes if it contains spaces.
::             -- RtnVar  An optional variable to be used to return the string length.
Set "s=#%~1"
Set "len=0"
For %%N in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
  if "!s:~%%N,1!" neq "" (
    set /a "len+=%%N"
    set "s=!s:~%%N!"
  )
)

Endlocal&if "%~2" neq "" (set %~2=%len%) else echo %len%
Exit /b

我要执行的操作将修改文件的日期,并将该日期的格式更改为YYYYMMDD。我希望将修改日期附加到文件名中。我可以在此文件夹中存放多天的文件,并且每个文件的修改日期都可能不同。

请不要将此问题标记为重复的问题,因为在这里找不到这种方法。

我正在尝试测试日期字符串的长度,以便可以处理类似日期1/1/2019(长度为8)vs 1/13/2019(长度为9)vs 10/1/2019(长度为9) vs 10/22/2019(长度为10),然后使用if语句以类似!fdate123:〜5,9 !! fdate123:〜0,1 !! fdate123:〜2,2之类的方式适当地解析日期! -我还没有完成。

我尝试使用dir /T:W testfiles*.*来获取日期并运行findstr,但我对findstr的理解还不够。

我还尝试将其从forfiles /M BC_Services_Adjustment* /C "cmd /c echo @fdate"中拉出,并继续进行下去。

也许有人有更好的解决方案,我想我的眼前一片混乱。有人知道如何获取文件夹中每个文件的日期修改时间戳,如何将其转换为YYYYMMDD格式的变量,然后将其附加到文件夹中的所有文件中?

注意:我不是在寻找有关此问题的Powershell解决方案,请不要浪费您的时间来发布Powershell答案。

更新#2 (5/21/19) 我尝试了magoo的代码,但仍需要一种解决方案来重命名文件。

@echo off
pushd "\\server\folder"
SETLOCAL EnableDelayedExpansion

FOR /F "TOKENS=2" %%A IN ('WHERE /T "*.csv"') DO (
     for /f "tokens=1-3delims=/-." %%i in ("%%A") do (
     set "mm=00%%i"&set "dd=00%%j"&set "yy=0000%%k"
     set "fdate123=!yy:~-4!!mm:~-2!!dd:~-2!"
     )
rem echo to test if date modified matches to the right filenames. 
echo !fdate123! ^& %%A
rem ren "%%~nxA" "%%~nxA!fdate123!"
)
pause

我尝试使用ren "%%~nxA" "%%~nxA!fdate123!",但找不到文件。可能超级简单。 如果有人可以使用magoo的代码进行重命名,而不仅仅是回显我可以奖励这个问题的日期。

5 个答案:

答案 0 :(得分:2)

请确保指定扩展名,以便bat文件位于该目录中,也不会重命名。

@echo off pushd "\\server\path123" SETLOCAL EnableDelayedExpansion FOR /r %%f IN (*.csv, *.txt) DO SET filedatetime=%%~tf & ren "%%~nf.*" "%%~nf!filedatetime:~6,4!!filedatetime:~0,2!!filedatetime:~3,2!%%~xf

答案 1 :(得分:1)

FOR /F "TOKENS=2" %%A IN ('WHERE /T "testfiles*.*"') DO (
 for /f "tokens=1-3delims=/-." %%i in ("%%A") do set "mm=00%%i"&set "dd=00%%j"&set "yy=0000%%k"
 set "fdate123=!mm:~-2!!dd:~-2!!yy:~-4!"
 echo !fdate123!
)

应该允许您根据自己的意愿构建数据。

内部if使用分析mm所指定的分隔符作为文字,适当地分配ddyy%%A。每个前缀以适当数量的零开头。然后使用子字符串选择字符串的最后2/4个字符来构造所需的字符串,从而获得8个字符的输出。

我使用dd/mm/yyyy格式,但尚未实际测试过此方法,但应根据您的要求进行操作应该很明显,唯一的问题实际上是如何处理{{1} }}日期(如果有问题的话)。

答案 2 :(得分:1)

是的,我读到您不需要任何PowerShell答案。请确保不要选择此答案。我没有浪费时间为您写点东西。这是给其他可能会受益的人的。

[CmdletBinding()]
Param (
    [Parameter(Mandatory=$true)]
    [string]$CommandName
)

$dirlist = @('.') + ($Env:Path.Split(';'))
$extensions = @('') + ($Env:PATHEXT.Split(';'))

$results = foreach ($dir in $dirlist) {
    if (($dir) -and ($dir -ne '')) {
        if (Test-Path -Path $dir -ErrorAction SilentlyContinue) {
            # The directory path exists.
            # Check for presence of the file with any executable extension.
            $dirhash = @{}

            foreach ($extension in $extensions) {
                Get-ChildItem -File -Path $dir -Filter "$CommandName$extension" |
                    ForEach-Object {
                        # If the file name is not already in the hash, add it to the hash
                        # and output it in the pipeline.
                        if (-not $dirhash.ContainsKey($_.Name)) {
                            $dirhash.Add($_.Name,1)
                            $_
                        }
                    }
            }
        }
    }
}

$results | ForEach-Object {
    Rename-Item -LiteralPath $_.FullName -NewName ($_.BaseName + $($_.LastWriteTime.ToString('yyyyMMdd')) + $_.Extension)
}

更新:

现在已经知道OP的意图,这是一个简单得多的问题。一旦确定文件将被正确重命名,请从-WhatIf cmdlet中删除Rename-Item

Set-Location -Path '//server/sharename'

Get-ChildItem -File -Filter 'testfiles*.*' |
    ForEach-Object {
        Rename-Item -LiteralPath $_.FullName -NewName ($_.BaseName + $($_.LastWriteTime.ToString('yyyyMMdd')) + $_.Extension) -WhatIf
    }

答案 3 :(得分:0)

我用自己的纯批处理解决方案解决了这个问题。 修改日期,将其以YYYYMMDD格式附加到目录中的任何文件名。我确实太复杂了,不敢相信我在设定赏金之前没有提出这个建议。大声笑

pushd "\\server\folder"
SETLOCAL EnableDelayedExpansion
FOR /r %%f IN (*) DO SET filedatetime=%%~tf & ren "%%~nf.*" "%%~nf!filedatetime:~6,4!!filedatetime:~0,2!!filedatetime:~3,2!%%~xf" 

答案 4 :(得分:-1)

我相信的输出格式是一致的,所以我建议将其作为可能的单行选项:

@PushD "\\server\folder" 2>Nul&&For /F "Tokens=1-4*Delims=/  " %%A In ('RoboCopy . $ testfiles*.* /L /NS /NJS /NJH /NDL /NC /TS')Do @Ren "%%E" "%%A%%B%%C-%%~nxE"

或者,根据您编辑的其他示例代码,更可能是您需要的:

@PushD "\\server\folder" 2>Nul&&For /F "Tokens=1-4*Delims=/  " %%A In ('RoboCopy . $ testfiles*.* /L /NS /NJS /NJH /NDL /NC /TS')Do @Ren "%%E" "testfiles%%A%%B%%C%%~xE"

如果每个重命名的文件都再次通过for循环运行,则可能需要从单行解决方案扩展此文件,以防止它发生。

在两个代码示例中,Delim项都是 / TAB