D M
D M

Reputation: 320

change the time output of the time variable in windows command line to use in batch file

Goal: Backup files from subdirectories with a specific extension to another directory using a batch file.

forfiles /P C:\Users\user\Desktop\testdest\ -D 3 /C "cmd /c IF @isdir == TRUE rd /S /Q @path" 
mkdir C:\Users\user\Desktop\testdest\%date%
FOR /R C:\Users\user\Desktop\testsrc\ %%A in (*.txt) do (
echo %%A
copy "%%A" "C:\Users\user\Desktop\testdest\%DATE%\%time:~0,2%_%time:~3,2%_%time:~6,2%_%time:~9,2%_%%~nxA
)

I tried multiple ways finding a way to make the file names unique. Unfortunately there are files in the subdirectories that have the same name as files in other subdirectories, so to make them unique in the target directory, they need a pre- or postfix that makes them unique. Tried a counter variable, but could not figure out how to increment it. I ended up trying to use the time variable, but it seems to stay the same in the whole batch file run.

Output is like this:

copy "C:\Users\user\Desktop\testsrc\sub\subsub\311.txt" "C:\Users\user\Desktop\testdest\01.02.2018\ 9_24_31_52_311.txt

copy "C:\Users\user\Desktop\testsrc\sub\subsub\312.txt" "C:\Users\user\Desktop\testdest\01.02.2018\ 9_24_31_52_312.txt

the time output stays the same, what is a problem, when there are multiple files with the same name.

So why is the time output not changing the millisecond?

Upvotes: 1

Views: 646

Answers (4)

D M
D M

Reputation: 320

thank you so much @Magoo and @npocmaka

it worked like a charme.

what confused me is that in the batch output, the !time! variables are not shown as expanded.

for example the output of

SETLOCAL EnableDelayedExpansion
Set timeexpand=!time:~0,2!_!time:~3,2!_!time:~6,2!_!time:~9,2!
copy "%%A" "C:\Users\user\Desktop\testdest\%DATE%\!timeexpand!_%%~nxA

is

copy "C:\Users\user\Desktop\testsrc\sub\subsub\331.txt" "C:\Users\user\Desktop\testdest\01.02.2018\!timeexpand!_331.txt

while the variables are not shown "as expanded" in the copy command "echo", the file names the script produces have the right timestamp.

for exmaple

10_18_28_59_1.txt
10_18_28_60_2.txt
10_18_28_61_3.txt

My final script looks like this:

eventcreate /L APPLICATION /SO backup /T INFORMATION /ID 337 /D "Starting copy of database files"
SETLOCAL EnableDelayedExpansion
forfiles /P D:\backup\bckup\ -D 3 /C "cmd /c IF @isdir == TRUE rd /S /Q @path" 
mkdir D:\backup\bckup\%date%
FOR /R D:\dbs %%F in (*.mdf) do ( 
timeout 1
Set timeexpandmdf=!time:~0,2!_!time:~3,2!_!time:~6,2!_!time:~9,2!
copy "%%F" "D:\backup\bckup\%date%\%%~nF_!timeexpandmdf!_%%~xF" 
)
FOR /R D:\dbs %%F in (*.ldf) do (
timeout 1
Set timeexpandldf=!time:~0,2!_!time:~3,2!_!time:~6,2!_!time:~9,2!
copy "%%F" "D:\backup\bckup\%date%\%%~nF_!timeexpandldf!_%%~xF" 
)
echo %DATE% %time% >> d:\backup\file.age
ENDLOCAL
eventcreate /L APPLICATION /SO backup /T INFORMATION /ID 337 /D "copy of database files done"

Upvotes: 1

lit
lit

Reputation: 16226

This seems clearer to me in PowerShell. When you are confident that the correct files will be copied with the correct names, remove the -WhatIf from the Copy-Item cmdlet.

Doing it in PowerShell relieves you of having to consider what the local date and time format requires.

$testsrc = 'C:\src\t\ct1'
$testdest = 'C:\src\t\ct2'
$thedate = Get-Date -Format 'yyyyMMdd'

Remove-Item -Path $testdest\* -Recurse
New-Item -Path $testdest -Name $thedate -ItemType 'directory' | Out-Null
Get-ChildItem -Path $testsrc -Recurse -Filter *.txt |
    ForEach-Object { Copy-Item -Path $_.FullName -Destination "$testdest\$thedate\$(Get-Date -Format 'HH_mm_ss_ffff_')$($_.Name)" -WhatIf }

One thing I notice about this is that the millisecond value does not always change often enough for every file to have a different timestamp. That could be a problem if you have files of the same name in two different directories of the source.

Upvotes: 1

npocmaka
npocmaka

Reputation: 57252

Try with delayed expansion:

setlocal enableDelayedExpansion
forfiles /P C:\Users\user\Desktop\testdest\ -D 3 /C "cmd /c IF @isdir == TRUE rd /S /Q @path" 
mkdir C:\Users\user\Desktop\testdest\%date%
FOR /R C:\Users\user\Desktop\testsrc\ %%A in (*.txt) do (
  echo %%A
  copy "%%A" "C:\Users\user\Desktop\testdest\%DATE%\!time:~0,2!_!time:~3,2!_!time:~6,2!_!time:~9,2!_%%~nxA
)

Mind that the %time% could differ on different machines as it relies on local settings.

Upvotes: 2

Magoo
Magoo

Reputation: 79982

SETLOCAL ENABLEDELAYEDEXPANSION

FOR /R C:\Users\user\Desktop\testsrc\ %%A in (*.txt) do (
echo %%A
copy "%%A" "C:\Users\user\Desktop\testdest\!DATE!\!time:~0,2!_!time:~3,2!_!time:~6,2!_!time:~9,2!_%%~nxA
)

ENDLOCAL

Please use the search facility to read many articles on delayed expansion to find out why.

Upvotes: 0

Related Questions