2013-02-10 2 views
1

Я потратил много часов, пытаясь справиться с этим и не повезло.Перемещение и переименование файлов из папки в папку в виде файла .bat и добавление измененной даты в начале

Сценарий: Имеют несколько разных имен файлов, но одно и то же расширение в папке. На сервере Windows 2008 64 бит. Хотите переместить их в другую папку, используя расписание пакетной работы. .летучая мышь. Во время перемещения я хочу переименовать их, чтобы включить их последнюю измененную дату. Я пытаюсь поставить в этот формат:

yyyymmddhhmmss-name.zip 

Я посмотрел на PowerShell и for команды и просто не может работать это.

Я нашел эту 3-строчную часть кода, и она хорошо работала на Windows 7, но не на Windows Server 2008!

@echo off 
set Date=%date:~10,4%%date:~4,2%%date:~7,2% 
move d:\Test\*.zip d:\Test1\*%Date%.zip 

На сервере он не мог понять *%Date%. Как только я удалил *, он сработал. Я пробовал разные варианты с кавычками и т. Д., Но не работал. Я понимаю, что дата не является решением, которым я занимаюсь, но если я не смогу заставить эту простую линию работать, это не имеет значения для остальных.

О, и смещения действительно работали, поэтому я получил дату для появления yyyymmdd. Я избегал PowerShell, так как мне нехорошо, и я также посмотрел на VBS. Но это не сильные стороны. Может ли кто-нибудь помочь?

Я знаю, что многие вопросы там похожи, но ничего совершенно не соответствует тому, что я пытаюсь сделать.

+0

Вы говорите, что вы хотите предварять последние измененные данные и время файла, но ваш код использует текущую дату и время. Кого вы действительно хотите? – dbenham

ответ

0

Вы можете сделать это с помощью команды wmic. Это позволяет вам получать текущие дату и время, не затрагивая региональные настройки. В то же время он также поможет вам переименовать zip-файл.

@echo off 
SETLOCAL EnableDelayedExpansion 

for /f "skip=1 tokens=1-6 delims= " %%a in ('wmic path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') do (
    IF NOT "%%~f"=="" (
     set /a FormattedDate=10000 * %%f + 100 * %%d + %%a 
     set /a FormattedTime=%%b * 10000 + %%c * 100 + %%e 
    ) 
) 

for /f %%f in ("D:\Test*.zip") DO set filename=%%~nf 

move "D:\Test*.zip" "D:\%FormattedDate%%FormattedTime%-%filename%.zip" 

Надеюсь, это поможет.

+0

Wow Это был быстрый ответ! –

+0

Я добавил код в bat-файл и изменил его, чтобы указать на другой каталог, но он терпит неудачу. получите ту же ошибку, что и я получил 14 часов назад. то есть: Имя файла, имя каталога или синтаксис метки тома неверны. Интересно, что ваш код и когда я вошел в него, отсутствует «\» после слова Test в команде move. Есть ли где-нибудь еще его недостающие? –

+0

Ahh, но это также не делает модифицированное время. Мне нравится то, что ты сделал. –

0

Вы можете использовать цикл FOR и применить модификатор ~t к переменной цикла для доступа к последней временной отметке последнего файла. Вам нужно будет отрегулировать исходное значение временной метки до необходимого формата, прежде чем использовать его с помощью команды MOVE. Вот пример того, как вы могли бы сделать это:

@ECHO OFF 
FOR %%I IN ("D:\Test\*.zip") DO (
    SET lmdate=%%~tI 
    SETLOCAL EnableDelayedExpansion 
    SET lmdate=!lmdate:~6,4!!lmdate:~3,2!!lmdate:~0,2!!lmdate:~11,2!!lmdate:~14,2! 
    MOVE "%%I" "D:\Test1\!lmdate!-%%~nxI" 
    ENDLOCAL 
) 

Следует отметить, что точность метки времени, возвращаемой переменной цикла с модификатором ~t ограничивается минут, так что, если вам действительно нужно, чтобы быть секунд , как предлагает ваш пост, это не может быть для вас решением.

В любом случае, так работает сценарий.

На каждой итерации переменной цикла %%I присваивается имя файла. Модификатор ~t дает указание переменной разрешить последнюю временную метку соответствующего файла.

lmdate переменных инициализирован с первой меткой времени, возвращаемый %%~tI (первым SET lmdate заявлением), а затем значение перестраивается, чтобы приспособить к формату yyyyMMddHHmm (второе SET lmdate заявления).Обратите внимание, что поскольку формат оригинальной временной метки зависит от локали системы, вам может потребоваться изменить эту вторую инструкцию SET, чтобы настроить ее на вашу конкретную систему. Выше сценарий предполагает следующий формат:

dd.MM.yyyy HH:mm 

SETLOCAL EnableDelayedExplansion заявления, которое вы можете увидеть выше, необходимо для доступа к фактической lmdate значения внутри тела цикла. В случае, если вы не знаете, «нормальное» (%) расширение переменных окружения в командах блоков не работает, когда значение установлено и извлекается в том же командном блоке. Вот где отсроченное расширение пригодится. Сначала вам нужно включить его, а затем использовать другой синтаксис расширения (! s вместо %).

Вы можете увидеть другие модификаторы, используемые в скрипте, а именно ~n и ~x (~nx при использовании вместе). Первое разрешает только имя файла (без пути или расширения), а второе - только с расширением. Существуют и другие модификаторы, и они задокументированы в встроенной справке команды FOR (FOR /?).

+0

Я рад, что ушел минут, а не секунд. Я следую за файлами, измененными отметками времени, чтобы быть в названии. Я вставил этот скрипт в bat-файл, запустил его, но получил обычную синтаксическую ошибку. Я не получаю никаких кодов ошибок. Я что-то упускаю? –

+0

Возможно, это возможно, если только у меня нет. Не могли бы вы рассказать о точном положении синтаксической ошибки? Возможно, вы могли бы запустить сценарий, не отрывая эхо, чтобы увидеть оскорбительную линию? В настоящее время я не вижу никакой проблемы, но я все еще смотрю на нее. –

+0

В моем опубликованном скрипте была опечатка. Пожалуйста, попробуйте сейчас. –

1

WMIC может использоваться, чтобы получить последнюю измененную метку времени для дробной второй точности. Первые 14 символов дают отметку времени точно в том формате, который вы ищете.

Вот быстрое решение, которое делает именно то, что вы просили:

@echo off 
for /f "skip=1 delims=" %%A in (
    'wmic datafile where "drive='d:' and path='\\test\\' and extension='zip'" get lastModified^,name' 
) do for /f "tokens=1*" %%B in ("%%A") do (
    set "timestamp=%%B" 
    set "file=%%~fC" 
    set "fileName=%%~nxC" 
    setlocal enableDelayedExpansion 
    move "!file!" "d:\test1\!timestamp:~0,14!-!fileName!" 
    endlocal 
) 

Выше привередливы, если вы хотите изменить требования. Ваша команда WMIC может занять некоторое время, если вы не будете осторожны, и есть некоторые маски файлов, которые просто невозможно эмулировать с помощью WMIC.

Ниже представлено гораздо более медленное решение, которое очень удобно. Вы передаете маску исходного файла и путь назначения в качестве параметров. Предположим, сценарий называется «addTimeStamp.bat», то вы будете использовать addTimeStamp "d:\test\*.zip" "d:\test1"

@echo off 
setlocal disableDelayedExpansion 
set "filePath=" 
if "%~2" neq "" for /f "eol=: delims=" %%F in ("%~2\") do set "filePath=%%~fF" 
for %%F in (%1) do (
    set "file=%%~fF" 
    set "fileName=%%~nxF" 
    setlocal enableDelayedExpansion 
    for /f "skip=1" %%A in (
    'wmic datafile where "name='!file:\=\\!'" get lastModified' 
) do for /f %%A in ("%%A") do (
    set "timestamp=%%A" 
    move "!file!" "!filePath!!timestamp:~0,14!-!fileName! 
) 
    endlocal 
) 
0

Я сделал один PowerShell скрипт, чтобы делать то, что вы хотите.

Сценарий: -

$src=""  # Source Path of Files to move 
$trg=""  # Destination folder 
$a=Get-ChildItem $SRC 
IF($a) 
{ 
    for($i=0; $i -le ($a.Count - 1); $i++) 
    { 
     $fileName=$a[$i].Name 
     $fileNameWithoutExtension=$fileName -replace ".zip", "" 
     $dirPath=$a[$i].DirectoryName 
     $lastModifiedDate=$a[$i].LastWriteTime 
     $LMFDate=($lastModifiedDate).ToString("yyyy-MM-dd-hh-mm-ss"); 
     $srcFile="$dirPath\$fileName" 
     move-Item $srcFile "$trg\$LMFDate-$fileName" 
    } 
}