How get only modification year using batch script? - windows

I have a problem
i need modification date of file. And i use windows batch script. But i can't get modification date and split them.
i currently using this command
for /f %a in ('dir /b') do #echo %a %~ta
result
file89401.txt 06/18/2005 05:37 AM
file8941.txt 11/21/2000 03:48 PM
file89411.txt 09/02/2008 02:14 PM
file89421.txt 03/01/2012 02:06 PM
file89431.txt 10/23/2001 06:48 AM
file89441.txt 10/27/2010 10:21 AM
file89451.txt 11/11/2011 05:40 AM
file89461.txt 11/23/2000 02:48 AM
file89471.txt 10/10/2001 01:28 AM
file89481.txt 07/14/2000 10:17 AM
file89491.txt 02/21/2004 10:24 PM
file89501.txt 03/12/2011 09:42 AM
file8951.txt 09/26/2003 11:31 PM
file89511.txt 08/17/2001 02:31 AM
file89521.txt 01/01/2004 01:11 PM
and i need only modification date and following format
2005/06/18
2000/1/21
2008/09/02
2012/03/01
2001/10/23
2010/10/27
2011/11/11
2000/11/23
2001/10/10
2000/07/14
2004/02/21
2011/03/12
2003/9/26
2001/08/17
2004/01/01
please help me,, sorry my bad English :(

Let's say you want to see modified date of files under directory C:\Users\test in format yyyy/mm/dd, below works perfectly for you:
#echo off
setlocal
for %%F in ("C:\Users\test\*") do (
for /f "tokens=1,2,3 delims=/ " %%A in ("%%~tF") do (
echo %%C/%%A/%%B
)
)
Result:
2013/12/21
2013/11/19
2012/12/28
2012/10/25
2011/10/25
2011/11/09
2010/12/21

findstr can only output Date/Time, not Date only.
You can fix it with some code or use a command that does what you want:
forfiles /c "cmd /c echo #fdate"
this is not a well knwon command, but it does give you the dates.
For more info see forfiles /?
to format the date to the desired format use:
for /f "tokens=1,2,3 delims=." %%a in (' forfiles /m *.* /c "cmd /c echo #fdate" ') do echo %%c/%%b/%%a
(Attention, this is language-dependent This line is for german format ("25.12.2013")
For your format echo %%c/%%a/%%b should do the trick)
EDIT
just noticed, you want no leading zero on day or month.
#echo off
setlocal enabledelayedexpansion
for /f "tokens=1,2,3 delims=." %%a in (' forfiles /m *.* /c "cmd /c echo #fdate" ') do (
set dat=%%c/%%a/%%b
set dat=!dat:/0=/!
REM replaced "/0" with "/"
echo %!dat!
)

From the prompt,
for %a in (*.*) do #for /f "delims=/ " %i in ("%~ta") do #echo %k/%i/%j
should deliver the goods.
As a batch file,
#echo off
for %%a in (*.*) do for /f "delims=/ " %%i in ("%%~ta") do echo %%k/%%i/%%j

Related

ZIP and delete files older than 7 days using 7ZIP and CMD

I have about 20 000 files in the folder, I want to zip and delete files older than 7 days. I tried this script, but it works very slow:
Set TDate=%date:~6,4%%date:~3,2%%date:~0,2%
for /f "delims=" %%i in ('
forfiles /p C:\ARCHIVE /s /m *.txt /d -7 /c "cmd /c echo #path"
') do (
"%ProgramFiles%\7-Zip\7z.exe" a "C:\ARCHIVE_%TDate%.zip" %%i
del /a /f %%i
)
Please advise how to make it work faster.
Besides usage of forfiles which is very slow (but inevitable for this script, I think), the main decelerating part of your script is the modification of the archive in every single loop iteration. Instead, you should do the archiving once only, perhaps using a list file, then let the archiving tool delete files it successfully compressed on its own:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_ROOT=C:\ARCHIVE"
set "_PATTERN=*.txt"
set "_LIST=%TEMP%\%~n0.tmp"
set "_ARCHIVER=%ProgramFiles%\7-Zip\7z.exe"
rem // Get current date in locale-independent format:
for /F "tokens=2 delims==" %%D in ('wmic OS get LocalDateTime /VALUE') do set "TDATE=%%D"
set "TDATE=%TDATE:~,8%"
rem // Create a list file containing all files to move to the archive:
> "%_LIST%" (
for /F "delims=" %%F in ('
forfiles /S /P "%_ROOT%" /M "%_PATTERN%" /D -7 /C "cmd /C echo #path"
') do echo(%%~F
) && (
rem // Archive all listed files at once and delete the processed files finally:
"%_ARCHIVER%" a -sdel "%_ROOT%_%TDATE%.zip" #"%_LIST%"
rem // Delete the list file:
del "%_LIST%"
)
endlocal
exit /B

set variable in forfiles in for cycle

#Echo On
FOR %%f IN (*.jpg) DO (
forfiles /M "%%f" /C "cmd /V:ON /c set fn=#ftime"
echo %%fn%%
)
pause
I want to get #ftime in FOR loop, but this isn't working. Maybe there is another way to get modify time of the file?
In your method, you are setting a variable fn within the cmd instance that is opened by forfiles, but this variable is no longer available in the cmd instance that runs your script.
You can use the ~t modifier of the for variable (so %%~tf in your code) to get the modification date and time, then split off the time portion by substring expansion (see set /?), if the featured resolution of minutes is sufficient (the "%%~nxF" portion just precedes the returned time with the current file name):
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for %%F in ("*.jpg") do (
set "FTIME=%%~tF"
rem The following line depends on region settings:
echo "%%~nxF": !FTIME:~11!
)
endlocal
pause
Alternatively, you can use a for /F loop to split off the time part from the date:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%F in ("*.jpg") do (
for /F "tokens=1,* delims= " %%I in ("%%~tF") do (
echo "%%~nxF": %%J
)
)
endlocal
pause
If you require a resolution of seconds as supported by forfiles, you need to echo the #ftime value within forfiles and capture that by a for /F loop, which iterates once only per each file (time) (#file returns the current file name, which is then held by "%%~K"):
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%F in ("*.jpg") do (
for /F "tokens=1,* delims=|" %%K in ('
forfiles /M "%%~F" /C "cmd /C echo #file^|#ftime"
') do (
echo "%%~K": %%L
)
)
endlocal
pause
Depending on your application, you might not need a separate for loop to walk through *.jpg files, because forfiles could do that on its own:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=1,* delims=|" %%K in ('
forfiles /M "*.jpg" /C "cmd /C echo #file^|#ftime"
') do (
echo "%%~K": %%L
)
endlocal
pause
You cannot set variables in your batch file from a forfiles call because that one will always spawn a new shell. forfiles is a program, not a built-in command.
However, you can get the modification time with %%tf in your loop, without forfiles:
setlocal enabledelayedexpansion
FOR %%f IN (*.jpg) DO (
set "fn=%%~tf"
echo !fn!
)
If you need exactly FORFILES, just write output to tempfile:
...
set file=temp.txt
...
FORFILES /M "%%f" /C "cmd /c echo #ftime >> %file%"
FOR /F "usebackq tokens=1,*" %%a In ("%file%") Do (Set fn=%%a | echo %fn%)
DEL %file% /q

Batch Script Parsing Dir Command

Hello newbie looking for some help. I am trying to write a script to search all files and folders in my drive which have a certain identifier. For example "ID -"
I was using the following to get files and directories listed in a log file:
dir ID * /A:-D-H /B /S >> C:\FileCatalogue.log 2>> C:\FileCatalogue.log
dir ID * /A:D-H /T:C /S >> C:\DirCatalogue.log 2>> C:\DirCatalogue.log
However I want the output to be in 3 tabbed columns:
FILE {tab} DIR {tab} ID
ID123 - YYYY - myfile.txt {tab} C:/tmp/tmp {tab} ID123 - YYYY
etc..
etc...
Any help would be greatly appreciated!
Victor
try this:
for /f "tokens=1*delims=-" %%a in ('dir /a-d/b ID*') do echo %%a-%%b %cd% %%a
#echo off
for /f "delims=" %%A in ('dir /a:-d-h /b /s /t:c ID123*') do for /f "tokens=1,2,* delims=-" %%B in ("%%~nxA") do echo(%%~nxA %%~dpA %%B-%%C
Output
ID123 - YYYY - myfile.txt C:\Users\User\Desktop\ ID123 - YYYY

Display file name and creation time ONLY of all files in a directory tree

Host: Win 7
I have a product that I updated today (patched if you will). I would like to see specifically which files were added to the base installation directory tree.
The expected result would ONLY display creation timestamp and full file path/name. I do not want to see directory summary information or any other breaks in the data. The output would be a very straight forward looking listing like this:
08/06/2012 11:02 AM c:\my_product_install_path\folder3\new_file_3.xml
08/06/2012 11:01 AM c:\my_product_install_path\folder2\new_file_2.c
08/06/2012 11:01 AM c:\my_product_install_path\new_file_1.h
...
...
I think from this top-down listing of the full install directory tree, I can easily see the new files from the old files by scrolling down and looking for the first file with time older than X.
How can I do this either at the Windows command shell (or in a cygwin shell)?
"dir /s /b" is very close but it does not display the creation time stamp.
You might think that "dir /s /b /T:C" would work since /T:C is for displaying the creation time but no. The /T:C option does not "overide" the /b option to display the timestamp So, somehow I need to get the benefits of the /b option with the timestamp added in.
This is a cumbersome native solution for the command line, but it works :-)
for /d /r %F in (.) do #pushd "%F"&(for /f "eol= delims=" %S in ('2^>nul dir /tc /a-d *') do #for /f "tokens=1-4*" %A in ("%S") do #echo %A %B %C %~fE)&popd
It looks better when formatted across multiple lines in a batch file.
#echo off
for /d /r %%F in (.) do (
pushd "%%F"
for /f "eol= delims=" %%S in ('2^>nul dir /tc /a-d *') do (
for /f "tokens=1-4*" %%A in ("%%S") do #echo %%A %%B %%C %%~fE
)
popd
)
You might want to sort the list in reverse chronological order so that all the new files are clustered at the top. It is trivial to do a chronological sort within each directory using the DIR /ODN option. But it is quite tricky to sort chronologically across all the directories. That requires parsing the time stamp info and reformatting it in a way that allows SORT to produce a chronological listing. Unfortunately, parsing the time stamp is very locale dependent.
Here is a batch solution that works with the OP's locale setting. It sorts first chronologically by creation timestamp, then alphabetically by full file path.
#echo off
setlocal
set "tempFile=%temp%\listCreateTime%random%.txt"
>"%tempFile%" (
for /d /r %%F in (.) do (
pushd "%%F"
for /f "eol= delims=" %%S in ('2^>nul dir /tc /a-d *') do (
for /f "tokens=1-6* delims=/ " %%A in ("%%S") do (
if "%%D"=="12:00" (
echo %%C%%A%%B%%E00:00%%~fG*%%A/%%B/%%C %%D %%E %%~fG
) else (
echo %%C%%A%%B%%E%%D%%~fG*%%A/%%B/%%C %%D %%E %%~fG
)
)
)
popd
)
)
for /f "tokens=2 delims=*" %%A in ('sort /r "%tempFile%"') do echo %%A
del "%tempFile%"
It is also possible to use WMIC to get and sort the information. It is much simpler because the timestamp is already formatted in a way that allows SORT to sort it chronologically, so there is no need to parse. It is also locale independent - it should work on any Windows machine in the world that supports WMIC. But this method is slower, and the ouput is not as easy to read. Of course extra coding could be added to parse out substrings from the timestamp and reformat to a more familiar form.
#echo off
setlocal disableDelayedExpansion
set "tempFile=%temp%\listCreateTime%random%.txt"
>"%tempFile%" (
for /d /r %%F in (.) do (
set "folder=%%~pnxF\"
set "drive=%%~dF"
setlocal enableDelayedExpansion
2>nul wmic datafile where "drive='!drive!' and path='!folder:\=\\!'" get name, creationDate|findstr /brc:[0-9]
endlocal
)
)
sort /r "%tempFile%"
del "%tempFile%"
The timestamp is in YYYYMMDDhhmmss.ddddddzzzz
YYYY = year
MM = month
DD = day
hh = hour in 24 hour format
mm = minutes
ss = seconds
dddddd = microseconds
zzzz = timezone info expressed as number of minutes difference from GMT

How do I create a folder using the date and time?

I'm trying to do a quick and simple game backup script and it's not working for me. Here's what I have.
#echo off
:main
RD /S /Q "C:\Users\Citadel\Desktop\Minecraft_Backups"
mkdir "C:\Users\Citadel\Desktop\Minecraft_Backups\%date% - %time%"
XCOPY "C:\Users\Citadel\AppData\Roaming\.minecraft\saves" "C:\Users\Citadel\Desktop\Minecraft_Backups\%date% - %time%" /D /E /C /R /I /K /Y
echo %date% - %time% - Backup Complete >> log.txt
PING 1.1.1.1 -n 1 -w 900000 >NUL
goto main
Honestly the mkdir command was a shot in the dark, but nothing so far has worked so I tried it.
The problem is that %date% and %time% contain special characters that can't be used in directory names. Try this at the top of your script:
for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
for /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a%%b)
Or if you prefer 24-hour time, change the second line to:
for /f "tokens=1-2 delims=/:" %%a in ("%TIME%") do (set mytime=%%a%%b)
And then use %mydate%_%mytime% in place of %date% %time%.
Note that this may have regional issues, but if you confirm it working for your machine, for local backups it will always be fine.
Here's what I found that seems to work:
#setlocal enableextensions
set datestamp=%date:~-4,4%%date:~-10,2%%date:~7,2%
mkdir %datestamp%

Resources