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
Related
So some background information of what I'm trying to accomplish. I have a log file in a location that I am copying to another location and renaming with a timestamp in the name, but leaving the attributes of the file the same. I also have it to where depending on a variable, it may make this file hidden. This all works as intended, and is triggered through a vbscript. The thing I am now trying to accomplish is before copying this file, I want to look at it's last modified date. I then want to compare that to each of the files in this other storage location, and if this matches then the file in the storage folder will be moved to a subfolder to store duplicate files.
#echo off
::////CONFIGURATION////
:: Set source folder and target folder in quotations
Set source="C:\Users\cafogle\Desktop\TEST\Source"
Set target="C:\Users\cafogle\Desktop\TEST\Destination"
:: Set folder name of where to keep copied files with duplicate last modified dates, without quotations
Set dumpfolder=filedump
:: The file name (including extension) without quotations
Set file=Log.txt
:: The file extension without quotations
Set filetype=.txt
:: If you want the file copied to be hidden, set this variable to '+h' If not, change it to '-h'
Set hidden=+h
::////SCRIPT////
:: Move duplicate files based on last modified date
Set reffilename=%file:~0,1%*%filetype%
for /f "delims=" %%i in ('"forfiles /P %source%\ /M %file% /C "cmd /c echo #ftime" "') do set reffiletime=%%i
for /f "delims=" %%k in ('"forfiles /P %target%\ /M %reffilename% /C "cmd /c echo #ftime" "') do (
(set reftimetemp=%%k)
for /f "delims=" %%j in ('"forfiles /P %target%\ /M %reffilename% /C "cmd /c echo #file" "') do (
(set reffiletemp=%%j)
if (%reftimetemp%==%reffiletime%) (robocopy %target% %target\%dumpfolder% %reffiletemp% /mov /a+:r)
)
)
pause
:: Running robocopy
Robocopy %source% %target% %file% /a+:r
taskkill /F /IM robocopy.exe
:: Retrieve local date and time from PC and save it to MyDate variable
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x
set timestamp=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%_%MyDate:~8,2%_%MyDate:~10,2%_%MyDate:~12,2%
:: Set variable for new file name
Set newfilename=%file%_%timestamp%%filetype%
:: Directing the rename function to destination folder and file name, this will then rename the file with current date and time.
ren %target%\%file% "%newfilename%"
:: Determine if file should be made hidden and hide if necessary
attrib %target%\%newfilename% %hidden%
This is the entire batch file, but the only part that I am having issues with is:
:: Move duplicate files based on last modified date
Set reffilename=%file:~0,1%*%filetype%
for /f "delims=" %%i in ('"forfiles /P %source%\ /M %file% /C "cmd /c echo #ftime" "') do set reffiletime=%%i
for /f "delims=" %%k in ('"forfiles /P %target%\ /M %reffilename% /C "cmd /c echo #ftime" "') do (
(set reftimetemp=%%k)
for /f "delims=" %%j in ('"forfiles /P %target%\ /M %reffilename% /C "cmd /c echo #file" "') do (
(set reffiletemp=%%j)
if (%reftimetemp%==%reffiletime%) (robocopy %target% %target\%dumpfolder% %reffiletemp% /mov /a+:r)
)
)
I've tried just about everything I can find, but the main issue is finding a way to take the date from the source file, and then comparing it to each individual file and moving them individually based on the outcome.
Any assistance would be greatly appreciated, as I have exhausted every option I can find.
Thanks!
I am trying to write a batch script that recursively lists all directories and their files with *.js type in the below format:
For example, if I start with the C:\project directory
c:\project
project.js
project_time.js
c:\project\core
core.js
core_render.js
core_application.js
I tried to implement the above logic in code as follows:
#echo off
for /r %%f in (*.js) do (
echo %%f >> names.txt
)
pause
I was not able to print the directory under which the files are listed.
#echo off
setlocal disabledelayedexpansion
set "lastdir="
( for /r %%A in (*.js) do (
set "nextdir=%%~dpA"
setlocal enabledelayedexpansion
if /i not "!lastdir!" == "!nextdir!" (
rem Empty line and directory path.
if defined lastdir #echo(
#echo !nextdir!
)
endlocal
rem Filename.
#echo %%~nxA
set "lastdir=%%~dpA"
)
) > "names.txt"
The lastdir variable is to record the last directory path so it is echoed only once.
If lastdir is different to %%~dpA:
If lastdir is defined, then an empty line will be echoed.
Directory path of found file is echoed.
Filename is always echoed.
for modifiers dp is the drive and path. nx is the name and extension.
setlocal enabledelayedexpansion is used only where needed so paths with ! are not vulnerable.
I am not going to suggest a command line solution as it would be very long. Instead suggest use of tree command if the output format is suitable.
Here's an untested example, (I'm not expecting it to be quick if your base directory is large):
#Echo Off
(
For /F "Delims=" %%G In ('Dir /B /S /A:D "C:\Project" 2^> NUL') Do (
%__AppDir__%where.exe /Q "%%G":*.js 1> NUL 2> NUL
If Not ErrorLevel 1 (
Echo/
Echo %%G
For /F "EOL=| Delims=" %%H In ('%__AppDir__%where.exe "%%G":*.js')Do (
Echo %%~nxH
)
)
)
) 1> "names.txt"
Pause
If you prefer to run something from the Command Prompt, then try this version:
(For /F "Delims=" %G In ('Dir /B/S/AD "C:\Project" 2^>NUL')Do #(%__AppDir__%where.exe /Q "%G":*.js >NUL 2>&1&&(Echo/&Echo %G&For /F "EOL=|Delims=" %H In ('%__AppDir__%where.exe "%G":*.js')Do #Echo %~nxH)))>"names.txt"
Two simple ways to do this:
dir /S *.js
You get the answers, just as you requested.
FORFILES /S /M *.js /C "cmd /c echo #path"
You get complete path for every file.
thanks for helping out
I currently face some issues while working on a .bat file that deletes the Internet Explorer 11 cache specifically for this three files:
Analytics.swf
Deal.swf
Pricing.swf
Currently I use the code attached, but it deletes all files in the cache (OS = Windows 10):
#echo off
set DataDir=C:\Users\%USERNAME%\AppData\Local\Microsoft\Intern~1\
del /q /s /f "%DataDir%"
rd /s /q "%DataDir%"
set History=C:\Users\%USERNAME%\AppData\Local\Microsoft\Windows\History
del /q /s /f "%History%"
rd /s /q "%History%"
set IETemp=C:\Users\%USERNAME%\AppData\Local\Microsoft\Windows\Tempor~1
del /q /s /f "%IETemp%"
rd /s /q "%IETemp%"
set Cookies=C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Cookies
del /q /s /f "%Cookies%"
rd /s /q "%Cookies%"
C:\bin\regdelete.exe HKEY_CURRENT_USER "Software\Microsoft\Internet Explorer\TypedURLs"
The following batch script will loop through the 4 folders you provide and search for all three files (see how to loop through arrays in batch) in all subdirectories (dir /b /s /a:-d "%%~f").
If the script is fine for you remove the echo in front of the del command:
#echo off
set "filesDel[0]=Analytics.swf"
set "filesDel[1]=Deal.swf"
set "filesDel[2]=Pricing.swf"
set "dirDel[0]=%LocalAppData%\Microsoft\Intern~1"
set "dirDel[1]=%LocalAppData%\Microsoft\Windows\History"
set "dirDel[2]=%LocalAppData%\Microsoft\Windows\Tempor~1"
set "dirDel[3]=%AppData%\Microsoft\Windows\Cookies"
rem loop over all directories defined in dirDel array
for /f "tokens=2 delims==" %%d in ('set dirDel[') do (
if exist "%%~d" (
pushd "%%~d"
rem loop over all files defined in filedDel array
for /f "tokens=2 delims==" %%f in ('set filesDel[') do (
rem search for file and delete it
for /f "tokens=*" %%g in ('dir /b /s /a:-d "%%~f"') do (
echo del /f "%%~g"
)
)
popd
)
)
Note that I use the quotes in the set command like: set "name=content", this allows spaces in the path name without having the quotes in the variable content itself.
Command reference links from ss64.com:
set
for /f
dir
if
pushd
popd
del
rem
I have the following batch file
#echo off
Del *.tmp /s /Q
Del *.temp /s /Q
Del Thumbs.db /s /Q
pause
I need it to record how much data it has deleted in the following formats
How much in data (KB)
How many files it has deleted
Does any one know a code I could use?
#echo info about deleted files:
#for /f "delims=" %%a in ('dir /s /-c /a-s *.tmp^| findstr /i "File(s) Directory"') do (
#echo %%a
)
#del *.tmp /s /Q
Try this:
#echo off
setLocal enableDelayedExpansion
set filePattern=*.temp
set totalSize=0
for /F "tokens=* usebackq" %%a IN (`dir /b ^| findstr /R .!filePattern!$`) DO (
set size=%%~za
set /a totalSize=!totalSize! + !size!
)
del !filePattern! /s /Q
set /a totalSize=!totalSize! / 1024
echo Total size deleted (!filePattern!): !totalSize! KB
pause
You may have to change the !filePattern! accordingly based on your desired files to be deleted. Besides that, you may have to place this batch script on the same directory as the files to be deleted.
I have many files with the following structure:
1969/ar/1.jpg
1969/ar/2.jpg
1969/he/1.jpg
1969/he/2.jpg
1969/en/1.jpg
1969/en/2.jpg
1970/ar/1.jpg
etc...
I want to rename all of them, with one command, to one directory, while their names reflect their original folder location.
1969_ar_1.jpg
1969_ar_2.jpg
1969_he_1.jpg
1969_he_2.jpg
1969_en_1.jpg
1969_en_2.jpg
1970_ar_1.jpg
etc...
Is it possible to do so with one command or a batch file?
Thanks!
You may do that to move the files to the base folder with this command-line:
for /R %a in (*) do #set f=%a& set f=!f:%cd%\=!& move "%a" !f:\=_!
Execute it from the folder that contain the 1969, 1970... folders. IMPORTANT!: Delayed Expansion must be active in order for this line to work, so you must previously activate it executing cmd.exe with /V switch this way: cmd /V.
For example:
>xcopy test backup /s
test\1969\ar\1.jpg
test\1969\ar\2.jpg
test\1969\en\1.jpg
test\1969\en\2.jpg
test\1969\he\1.jpg
test\1969\he\2.jpg
test\1970\ar\1.jpg
7 File(s) copied
>cd test
>dir /B
1969
1970
>for /R %a in (*) do #set f=%a& set f=!f:%cd%\=!& move "%a" !f:\=_!
>dir /B
1969
1969_ar_1.jpg
1969_ar_2.jpg
1969_en_1.jpg
1969_en_2.jpg
1969_he_1.jpg
1969_he_2.jpg
1970
1970_ar_1.jpg
Modify the line this way to move the files to another folder:
for /R %a in (*) do #set f=%a& set f=!f:%cd%\=!& move "%a" "\other\folder\!f:\=_!"
Or via this Batch file:
#echo off
setlocal EnableDelayedExpansion
for /R %%a in (*) do set f=%%a& set f=!f:%cd%\=!& move "%%a" "\other\folder\!f:\=_!"
Run this from the base of the tree that contains all *.jpg files.
Change the target folder to where you want the files to go:
Test it on some samples first.
#echo off
for /f "delims=" %%z in ('dir "*.jpg" /b /s /a-d ') do (
for %%a in ("%%~dpz%\.") do (
for %%b in ("%%~dpa\.") do (
ren "%%z" "%%~nxb_%%~nxa_%%~nxz"
move "%%~dpz\%%~nxb_%%~nxa_%%~nxz" "c:\target\folder"
)
)
)
pause
try this (look at the output and remove the word echo before move, if it is OK):
#echo off &setlocal
for /d %%i in (19* 20*) do (
cmd /c "for /r "%%i" %%j in (*.jpg) do #for %%k in ("%%~dpj.") do #echo move "%%~j" "%%i_%%~nk_%%~nxj""
)