CMD / BAT получить дату изменения всех имен файлов и добавить к их имени - PullRequest
0 голосов
/ 18 мая 2019

У меня проблемы с этим скриптом.Я объясню ниже кодовый блок.

@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

То, что я пытаюсь сделать, это получить дату изменения файла и изменить формат этой даты, возвращенной на ГГГГММДД.Я хочу, чтобы измененная дата была добавлена ​​к имени файла.У меня могут быть файлы из нескольких дней в этой папке, и каждый файл может иметь свою дату изменения даты.

Пожалуйста, не помечайте это как дублирующий вопрос, потому что я не мог найти этот подход для этого здесь.

Я пытался проверить длину строки даты, чтобы я мог обрабатывать даты, такие как 01.01.2009 (длина 8) против 13.01.2009 (длина 9) против 01.10.2009 (длинаиз 9) против 22.10.2009 (длина 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" и от этого тоже ушел.

возможно, у кого-то есть лучшее решение, я думаю, что сейчас у меня беспорядок.Кто-нибудь знает, как получить метку времени изменения даты для каждого файла в папке, преобразовать ее в переменную в формате ГГГГММДД, а затем добавить ее во все файлы в папке?

Примечание: яНе ищите решения PowerShell для этого вопроса, не тратьте свое время на публикацию ответов PowerShell.

Обновление № 2 (21.05.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 ]

2 голосов
/ 22 мая 2019

Обязательно укажите свои расширения, поэтому, если ваш 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 голос
/ 19 мая 2019

Да, я читал, что вы не хотите никаких ответов 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)
}

ОБНОВЛЕНИЕ:

Теперь, когда намерение ОП известно, это гораздо более простая проблема.Если вы уверены, что файлы будут переименованы правильно, удалите -WhatIf из командлета 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
    }
1 голос
/ 18 мая 2019
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, dd и yy в зависимости от ситуации,используя заданные разделители, анализируя %%A как литерал.Каждому предшествует соответствующее количество нулей.Затем необходимая строка создается с использованием подстроки, выбирающей последние 2/4 символа строки, поэтому получается 8-символьный вывод.

Я использую формат dd/mm/yyyy и фактически не тестировал этот метод, номанипулирование им в соответствии с вашими требованиями должно быть очевидным, единственная проблема на самом деле заключается в том, как обрабатывать yy даты как отличные от yyyy дат, если это вызывает озабоченность.

0 голосов
/ 22 мая 2019

Я понял это на собственном, чистом пакетном решении.Принимает дату изменения, добавляет ее к любому имени файла в каталоге в формате ГГГГММДД.Я действительно слишком усложнял это, не могу поверить, что я не придумал это до назначения награды.лол

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" 
0 голосов
/ 18 мая 2019

Я полагаю, что вывод находится в согласованном формате, поэтому я бы предложил это как возможную единственную строку параметр:

@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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...