Windows Batch:Count the number of files deleted using forfiles command - windows

I have written a simple batch job for copying the files from one folder to another that are older than x-number of days using forfiles. But I need to count the number of files that have been copied. I tried various ways to do this but was unsuccessful. Could any body help me trough this?
#Echo off
Echo Starting the script for copying files to other folder.
set dt=%date:~10,4%-%date:~4,2%-%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%
set filesMovedCount=0
forfiles /p C:\symphonybackup\symphonybackup\Symphony\SymphonyArcheive /s /m *.* /d -30 /c "cmd /c echo #path >> C:\symphonybackup\symphonybackup\Symphony\%dt%.log & cmd /c copy #path C:\symphonybackup\symphonybackup\Symphony\SymphonyTemp"
Echo filesmovedcount:%filesMovedCount%
Echo finised copying the files

You could just pipe all of your copied file names to a file and then count the rows in the file. Here I added the additional stuff, you can just add the commands where the output gets piped to logfile where indicated. When done, it will echo the count and you delete the file.
#echo off
forfiles /p "rest of copy commands" >>logfile.txt
setlocal EnableDelayedExpansion
set "string=findstr /R /N "^^" logfile.txt | find /C ":""
for /f %%a in ('!string!') do set count=%%a
echo %count% files copied
del /Q logfile.txt

Mayby late answer to this, but when I try this:
set "string=findstr /R /N "^^" logfile.txt | find /C ":""
for /f %%a in ('!string!') do set count=%%a
I get one extra result since I get one empty row. So I did need have to add -1 to the result.
Atleast on my system...

Related

Windows batch file: move files that older than 10 days and the filename without a specific string

I am creating a batch file for task scheduler in Windows 7.
The logic is searching files in a folder, if the filename without a specific string, and it's older than 10 days, move the file to another folder.
I've tried so many commands but cannot achieve this (combine the findstr and date condition). And as I am quite new to batch commands. Could anyone please give me some scripts or advice?
Here is what I wrote for moving the files without specific string in the filename, but dont know where to put the date condition:
for /r %Path_new% %%H in ("*.avi") do (echo "%%~nH" |findstr /i "_connID=">nul ||((move /y "%%H" "%Path_achieve%" ) && (echo %date% %time% - %%H has been moved >> Log4BB.txt)) )
And if I put a date condition in a script, it will be like this but cannot get the files with a specific string in the filename:
forfiles /p %Path_new% /m *.avi /d -%Day_noconnid% /c "cmd /c if #fname like '*_connID=*' (echo #path will be moved)" >> Log4BA.txt
For robocopy, I don't know how to specify the files that i want to move. My scripts as below:
for /r %Path_new% %%G in ("*.avi") do (^
echo "%%~nG" |findstr /i "_connID=">nul ||(^
robocopy "%Path_new%"\"%%~nG%%~xG" "%Path_achieve%" /maxage:10 /mov)^
) >> Log4BC.txt
Finally, I got the answer. Robocopy has a /XF that allows me to put the condition for filename.
robocopy %Path_new% %Path_achieve% *.avi /mov /xf "*_connID=*.avi" /minage:%Day_noconnid% /log+:"Log4B.txt"
Working very good now. Thanks Squashman

Batch file to copy files from 1 day before and no more

imagine that I have 2 folders:
C:\FolderData (will be incremented daily with new files)
C:\FolderTemp (Needs to have only files from the day before executing, excluding hours/timestamp)
The FolderData will receive filenames that if not for date would be equals, as in:
SYS_PURCHASES_20170612.xls
SYS_PURCHASES_20170613.xls
SYS_PURCHASES_20170614.xls
If I run the .bat file today I need that only the SYS_PURCHASES_20170613.xls be copied over to FolderTemp.
I tried using robocopy but apparently it can't receive the same value for minage and maxage
robocopy "C:\FolderData" "C:\FolderTemp" /minage:1 /maxage:1
Also, if I try:
robocopy "C:\FolderData" "C:\FolderTemp" /minage:1 /maxage:2
It will bring both SYS_PURCHASES_20170612.xls and SYS_PURCHASES_20170613.xls, which is not what I need.
Other than that, I tried using forfiles but also with no avail.
forfiles /p C:\FolderData /D -1 /C "/C /copy /y #file C:\FolderTemp"
or even
forfiles /p C:\FolderData /D -1 /C "/C /copy /y C:\FolderData\#file C:\FolderTemp"
And other variables but it returns something along the line "the system can't return the specified file" times the number of files in the folder.
Note that there are other processes involved bellow that should be ignored, It's just that I can't figure out how to do the step above.
All steps my batch filed needs to do:
Copy from folder1 files from 1 day prior to folder2 (what I need help)
Remove last 9 digits from all files from folder2 (will remove the date, used the loop on this solution) so the file will be SYS_PURCHASES.xls
Move and replacing the files from folder2 to folder3 (using a simple move /y)
Since you want to touch the files from yesterday only, I would use forfiles, because this command only regards the date but not the time, when specifying the /D option. robocopy instead also regards the time, which is probably not what you want.
This is a possible way:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=C:\FolderData"
set "_TARGET=C:\FolderTemp"
set "_MASK=?*_????????.*"
set /A "_DAYS_AGO=1"
rem // Check given age and calculate interim value `PREV` needed for `forfiles`:
(if %_DAYS_AGO% LSS 0 set "_DAYS_AGO=0") & set /A "PREV=_DAYS_AGO+1"
rem // Let `forfiles` output the filtered files and capture them by `for /F`:
for /F "delims= eol=|" %%F in ('
rem/ Use two nested `forfiles` loops to filter for files of specified day: ^
^& forfiles /P "%_SOURCE%" /M "%_MASK%" /D -%_DAYS_AGO% ^
/C "cmd /C if #isdir==FALSE > nul 2>&1 forfiles /M #file /D -%PREV% || echo #file"
') do (
rem // Store current file name and extension:
set "FILE=%%~nF" & set "FEXT=%%~xF"
setlocal EnableDelayedExpansion
rem // Copy the file and remove the last 9 characters from its name:
> nul copy /Y "!_SOURCE!\!FILE!!FEXT!" "!_TARGET!\!FILE:~,-9!!FEXT!"
endlocal
)
endlocal
exit /B

For /f only outputting top level from forfiles /s

I have the following directory structure structure:
DirA
DirB
fileb1
fileb2
DirC
filec1
filec2
fileA1
my.appcache
fileA2
And I'm trying to write a batch file that will output the file names with their relative directories to a .appcache or .txt file.
Here is the script which lies in the directory above DirA
cd DirA
del /Q "my.appcache"
fsutil file createnew my.appcache 0
setlocal disableDelayedExpansion
for /f "delims=" %%A in ('forfiles /s /m *.* /c "cmd /c echo #relpath >> my.appcache" ') do (
set "file=%%~A"
setlocal enableDelayedExpansion
echo !file:~2!
endlocal
)
PAUSE
However, the script only sends DirA's contents to my.appcache. However, if i just let it echo to the cmd window, it lists all the files inside DirB and DirC too.
Can anyone see what I'm doing wrong?
EDIT: It's creating my.appcaches in DIRB and DIRC and outputting the relevant section to them.
Your script is a bit hard to follow because you are combining for /f with forfiles. Those two commands do a similar job so people typically use one or the other. Anyway, your issue is that you are appending to a file in the current directory, which changes as the forfiles command traverses the tree. You'll find a separate my.appcache file in each directory. You should instead do the redirection in one place:
(forfiles /s /m *.* /c "cmd /c echo #relpath") > my.appcache
(and you don't need any of the other scaffolding.)
By the way, if you want to search for ALL files (not just those containing a dot in their names) then the /m * option is the default, so you can just leave it out:
(forfiles /s /c "cmd /c echo #relpath") > my.appcache

Windows batch script for searching files based on file name,checks if the files are older than N days, if true, it deletes those files

I am a newbie to windows batch scripting. I have researched through the web and the site and tried out the solutions but none seem to give me the desired results.
This is what I want to achieve:
Search for files in a folder using a specific filename
show found files
Check the found files if they are older than 1 day
If true,delete those files
Else return message(Found files not older than 1 day)
From my research I was able to write a batch code that searches for file using a string, but unable to do step 2,3,4 and 5.
Kindly assist.
Here is my batch code:
#echo off & setlocal
set "MySearchString=Scheduled_error"
for /r %%a in (*) do for /f "delims=" %%i in ('echo("%%~na" ^| findstr /i "%MySearchString%"') do echo del "%%~fa"
Seems like a perfect task for FORFILES!
forfiles /p c:\SomePath\ /s /m *.* /c "cmd /c echo #path" will show you all files older than one day. You can modify the filter replacing *.* with the file name you are looking for.
To delete these files simply replace echo #path with del /y #path and add the /d -1 parameter:
forfiles /p c:\SomePath /s /m *.* /d -1 /c "cmd /c del /y #path"
The age of the files to delete is specified with the /d -1 switch where -1 means 1 day and older.

How to delete empty folders using windows command prompt?

I need to delete all empty folders from my application folder using windows command prompt?
How can I create a bat file like that?
Please help me.
You can use the ROBOCOPY command. It is very simple and can also be used to delete empty folders inside large hierarchy.
ROBOCOPY folder1 folder1 /S /MOVE
Here both source and destination are folder1, as you only need to delete empty folders, instead of moving other(required) files to different folder. /S option is to skip copying(moving - in the above case) empty folders. It is also faster as the files are moved inside the same drive.
A simpler way is to do xcopy to make a copy of the entire directory structure using /s switch. help for /s says Copies directories and subdirectories except empty ones.
xcopy dirA dirB /S
where dirA is source with Empty folders. DirB will be the copy without empty folders
for /f "usebackq" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"
from: http://blogs.msdn.com/b/oldnewthing/archive/2008/04/17/8399914.aspx
Of course I'd test it first without deleting before I do that command. Also, here's a modded version from the comments that includes folders with spaces:
for /f "usebackq delims=" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"
P.S. there are more comments in the blog post that might help you out so be sure to read those too before you try this out
You don't need usebackq:
FOR /F delims^= %%A IN ('DIR/AD/B/S^|SORT/R') DO RD "%%A"
Adding to corroded answer from the same referenced page is a PowerShell version http://blogs.msdn.com/b/oldnewthing/archive/2008/04/17/8399914.aspx#8408736
Get-ChildItem -Recurse . | where { $_.PSISContainer -and #( $_ | Get-ChildItem ).Count -eq 0 } | Remove-Item
or, more tersely,
gci -R . | where { $_.PSISContainer -and #( $_ | gci ).Count -eq 0 } | ri
credit goes to the posting author
from the command line:
for /R /D %1 in (*) do rd "%1"
in a batch file
for /R /D %%1 in (*) do rd "%%1"
I don't know if it's documented as such, but it works in W2K, XP, and Win 7. And I don't know if it will always work, but it won't ever delete files by accident.
This is a hybird of the above. It removes ALL files older than X days and removes any empty folders for the given path. To use simply set the days, folderpath and drive
#echo off
SETLOCAL
set days=30
set folderpath=E:\TEST\
set drive=E:
::Delete files
forfiles -p %folderpath% -s -d -%days% -c "cmd /c del /q #path "
::Delete folders
cd %folderpath%
%drive%
for /f "usebackq delims=" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"`
It will be worked fine. This is best way to delete old files and remove empty directories recursively.
following .bat file is,
forfiles /p [PATH] /s /m [FILE-PATTERN] /d -[DAYS] /c "cmd /c del #path"
for /f "delims=" %%d in ('dir [PATH] /s /b /ad ^| sort /r') do rd "%%d"
The placeholders needs to be replaced as follows (without the quotation marks):
[DAYS] = Max. age of the files in days, e.g. “10”
[PATH] = Path to search for old files and empty folders, e.g. “C:\Backup\”
[FILE-PATTERN] = Pattern that matches files to delete, e.g. “*.bkp”
The script has been successfully tested under Windows 7 and Windows Server 2003.
Install any UNIX interpreter for windows (Cygwin or Git Bash) and run the cmd:
find /path/to/directory -empty -type d
To find them
find /path/to/directory -empty -type d -delete
To delete them
(not really using the windows cmd prompt but it's easy and took few seconds to run)
#echo off
set /p "ipa= ENTER FOLDER NAME TO DELETE> "
set ipad="%ipa%"
IF not EXIST %ipad% GOTO notfound
IF EXIST %ipad% GOTO found
:found
echo DONOT CLOSE THIS WINDOW
md ccooppyy
xcopy %ipad%\*.* ccooppyy /s > NUL
rd %ipad% /s /q
ren ccooppyy %ipad%
cls
echo SUCCESS, PRESS ANY KEY TO EXIT
pause > NUL
exit
:notfound
echo I COULDN'T FIND THE FOLDER %ipad%
pause
exit
If you want to use Varun's ROBOCOPY command line in the Explorer context menu (i.e. right-click) here is a Windows registry import. I tried adding this as a comment to his answer, but the inline markup wasn't feasible.
I've tested this on my own Windows 10 PC, but use at your own risk. It will open a new command prompt, run the command, and pause so you can see the output.
Copy into a new text file:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\directory\Background\shell\Delete Empty Folders\command]
#="C:\Windows\System32\Cmd.exe /C \"C:\Windows\System32\Robocopy.exe \"%V\" \"%V\" /s /move\" && PAUSE"
[HKEY_CURRENT_USER\Software\Classes\directory\shell\Delete Empty Folders\command]
#="C:\Windows\System32\Cmd.exe /C \"C:\Windows\System32\Robocopy.exe \"%V\" \"%V\" /s /move\" && PAUSE"
Rename the .txt extension to .reg
Double click to import.
for /r "D:\Music" /d %F in (.) do #dir /b "%F" | findstr "^" >nul || rmdir %~fF
D:\Fun is the folder that contains empty folders
double quotation in the case of space in folder name (no need in this example)
A more modern and easier solution is:
forfiles /p C:\Path\To\Folder /c "cmd /c if #isdir==TRUE rd #file"
This will attempt to execute rd on all the directories located in C:\Path\To\Folder. Directories that have content in them will not be deleted.
If you exclude /p C:\Path\To\Folder then it'll run in the current directory.
If you add /s (before the /c) then it'll also look in sub-directories.
The following .cmd is an experiment (that works) to:
Deletes empty directories and included "Old"(-1days) files under %temp% & C:\Windows\Temp folders,
makes an cmd output log to a .txt file, about fouded & deleted folders/files .
%temp% = C:\Users(user)\AppData\Local\Temp | %userprofile%\AppData\Local\Temp
code:
:: This is a .cmd file
:: Use to:
:: Writes a Log about Temporary files & folders.
:: Cleans 'Windows Temp' folders/files. (%userprofile%\AppData\Local\Temp -&- %windir%\Temp)
:: - a 'Cleaning_LOGs.txt' will be created or updated in Documents Library. (%userprofile%\Documents\Cleaning_LOGs.txt)
::
#echo off
title Log&CleanTemp
: Set the Path of 'Log file' (%LogPath% variable)
set "LogPath=%userprofile%\Documents\Cleaning_LOGs.txt"
:: Note: ">> path\file.txt 2>&1" redirects cmd output to <path\to>\<log_file.txt>, (will be created if does not exist)
:: (if exist, adds the new log at the end of the file, without deleting previous logs)
: Set 'C:\Windows\Temp' (%WinTemp% var.)
set "WinTemp=%windir%\Temp"
: Seperator [Header] with Date-Time between (any) previous Logs in <log_file.txt>
echo: >> %LogPath% 2>&1
echo ======================================== >> %LogPath% 2>&1
echo %date% - %time% >> %LogPath% 2>&1
echo: >> %LogPath% 2>&1
echo Log Path: %LogPath% (this text file) >> %LogPath% 2>&1
echo: >> %LogPath% 2>&1
: Report Output & Log
:: Writes a log about temporary files & folders.
:: Note: ( %temp% = C:\Users\<user>\AppData\Local\Temp = %userprofile%\AppData\Local\Temp )
:: ( 'WinTemp' = C:\Windows\Temp = %windir%\Temp )
echo: >> %LogPath% 2>&1
echo __________ Empty (0 size) , Old (-1days) files: >> %LogPath% 2>&1
ForFiles /p "%temp%" /s /d -1 /c "cmd /c if #fsize==0 ECHO #path " >> "%LogPath%" 2>&1
ForFiles /p "%WinTemp%" /s /d -1 /c "cmd /c if #fsize==0 ECHO #path " >> "%LogPath%" 2>&1
echo: >> %LogPath% 2>&1
echo __________ All Old (-1days) files: >> %LogPath% 2>&1
ForFiles /p "%temp%" /s /d -1 /c "cmd /c ECHO #path " >> "%LogPath%" 2>&1
ForFiles /p "%WinTemp%" /s /d -1 /c "cmd /c ECHO #path " >> "%LogPath%" 2>&1
:: Note: "ForFiles" /p=Path /s=SubDir /d=Days(dd) /c=cmd "forfiles /?" for info about command's Variables (#path, #file, etc.)
: Get permissions (unlock files/folders) (OPTIONAL)
:: Uncomment to make it work, IF needed.
::echo: >> %LogPath% 2>&1
::ForFiles /p "%temp%" /s /d -1 /c "cmd /c TAKEOWN /f * /r /d y && ICACLS #file /grant *S-1-3-4:F /t /c /l /q"
: Clean proper files & Log it
:: Test: ForFiles /p "%temp%\" /s /d -1 /c "cmd /c if #fsize==0 DEL /f /s /q #file" >> "%LogPath%" 2>&1
:: ERROR: Invalid argument/option - '#fsize==0'
echo: >> %LogPath% 2>&1
echo __________ Deleted files: >> %LogPath% 2>&1
forfiles /p %temp%\ /s /d -1 /c "cmd /c DEL /f /s /q #path" >> "%LogPath%" 2>&1
forfiles /p %WinTemp%\ /s /d -1 /c "cmd /c DEL /f /s /q #path" >> "%LogPath%" 2>&1
echo: >> %LogPath% 2>&1
echo __________ Deleted empty directories: >> %LogPath% 2>&1
for /f "delims=" %%d in ('dir %temp%\ /s /b /ad ^| sort /r') do RD "%%d" >> "%LogPath%" 2>&1
for /f "delims=" %%d in ('dir %WinTemp%\ /s /b /ad ^| sort /r') do RD "%%d" >> "%LogPath%" 2>&1
:: Note: 'RD' = Remove-Directory (delete)
: Open Log file
:: this opens the log file [(my) Documents\Cleaning_LOGs.txt]
explorer.exe %LogPath%
:: https://stackoverflow.com/questions/7831286/how-to-delete-empty-folders-using-windows-command-prompt/46617314#46617314
Note that:
The trigger to Experiment with this, as part of a 'pre-process', was to prevent the specific (obsolete) driver of the (also obsolete) sound card from automatically reinstalling at each boot. And clean (ghosted) hidden Devices and more other. (...) (this note was just about to get an idea for the use)
So, in a few words:
This is the part that cleans up the 'temp' garbage left behind and gives a report.
well, just a quick and dirty suggestion for simple 1-level directory structure without spaces, [edit] and for directories containing only ONE type of files that I found useful (at some point from http://www.pcreview.co.uk/forums/can-check-if-folder-empty-bat-file-t1468868.html):
for /f %a in ('dir /ad/b') do if not exist %a\*.xml echo %a Empty
/ad : shows only directory entries
/b : use bare format (just names)
[edit] using plain asterisk to check for ANY file (%a\* above) won't work, thanks for correction
therefore, deleting would be:
for /f %a in ('dir /ad/b') do if not exist %a\*.xml rmdir %a
This can be easily done by using rd command with two parameters:
rd <folder> /Q /S
/Q - Quiet mode, do not ask if ok to remove a directory tree with
/S
/S - Removes all directories and files in the specified directory
in addition to the directory itself. Used to remove a directory tree.

Resources