Auto delete files in subfolders after a certain count value - windows

Can anyone please explain to me how batch scripts work in Windows? I have a folder that contains subfolders, and those contain images. I need a script that automatically deletes images from 7 and up in these subfolders, just to leave a maximum of 6 images in each subfolder, ideally the first 6 alphabetically. I found a few scripts, saved them as .bat, but I have no idea what to do next.
1
#echo off
setlocal
set /a cnt=0
set "keep=6"
for /f "eol=: delims=" %%F in ('dir /b /o-d /a-d *.jpeg') do (
if defined keep (
2>nul set /a "cnt+=1, 1/(keep-cnt)" || set "keep="
) else del "%%F"
)
2
#echo off
for /f "tokens=1* delims=:" %%a in ('dir /b /o-d *.jpeg ^| findstr /N "^"') do (
if %%a gtr 6 del "%%b"
)
3
for /f "skip=7 eol=: delims=" %%F in ('dir /b /o-d /a-d *.jpeg') do #del "%%F"
4
#echo off
setlocal enableextensions disabledelayedexpansion
rem How many elements to keep
set "keep=6"
rem Retrieve folder from batch arguments
set "folder=%~1"
rem If no folder indicated, use current active directory
if not defined folder for %%a in (.) do set "folder=%%~fa"
rem Ensure we are working in the correct folder
pushd "%folder%" && (
rem For each element in the folder, skipping the first n
for /f "skip=%keep% delims=" %%a in (' dir /b /on ') do (
rem If it is a folder, use rmdir, else use del
if exist "%%a\" ( echo rmdir /s /q "%%a" ) else ( echo del "%%a" )
)
rem Work done. Return to previous active directory
popd
) || (
rem Folder change failed
echo Target folder does no exist
)

I finally found a script that works the way I need it to
for /f %%a in ('dir /b /ad') do (
for /f "skip=6" %%b in ('dir /b %%a /on') do (
del %%a\%%b
)
)

Related

Batch delete files but keep 6 files?

I have a directory with lots of subfolders. I want to delete all files but keep the first 6 files for each subfolder. How can I batch do this on windows server 2012?
Change variables BaseDir and KeepFiles to fit your needs.
If the output looks ok, remove echo in the last line
:: Q:\Test\2018\05\02\SO_50129236.cmd
#Echo off & SetLocal
Set "BaseDir=Q:\Test\2018"
Set "KeepFiles=6"
Pushd "%BaseDir%" || (echo couldn't find BaseDir&Pause&exit /b 1)
For /F %%A in (
'dir /B /S /AD 2^>nul'
) do For /F "skip=%KeepFiles% delims=" %%B in (
'dir /B /A-D /ON "%%~fA\*" 2^>NUL'
) do Echo del "%%~fA\%%~nxB"

Delete all files inside all folders with a specific name with date before today

In my hard disk I have the following structure:
ROOTFOLDER
├───FOLDER1
│ └───TMPFOLDER
│ ├───FOLDERTODELETE1
│ ├───FOLDERTODELETE2
│ └───FOLDERTODELETE3
├───FOLDER2
│ └───TMPFOLDER
│ ├───FOLDERTODELETE4
│ └───FOLDERTODELETE5
└───FOLDER3
└───TMPFOLDER
├───FOLDERTODELETE6
├───FOLDERTODELETE7
└───FOLDERTODELETE8
I need to create a kind of script (I was thinking about a batch file, but any other solution will be appreciated) to delete all folders within each folders with a specific name (in this case TMPFOLDER) and created before today.
Following to your needs the batch script below will do what you need. Remove the echo in front of the rmdir command if it's okay for you. Take care that the script uses the current working directory. Remove /q if you want to be asked for each directory that should be deleted:
#echo off
set "tmpfolder=TMPFOLDER"
for /f "tokens=*" %%D in ('dir /b /a:d "*"') do (
for /f "tokens=*" %%E in ('dir /b /a:d "%%D\*" ^| findstr /l /x %tmpfolder%') do (
echo Found temp folder: "%%D\%%E"
for /f "tokens=*" %%F in ('dir /b /a:d "%%D\%%E\*"') do (
echo rmdir /s /q "%%D\%%E\%%F"
)
)
)
Edit #1:
The above script does not take care of the creation date of the folder that should be removed. You want only folders to be deleted which have a creation date before today. The following script takes care of that. Look here how to get dates of folder and here how to compare dates:
#echo off
setlocal EnableDelayedExpansion
set "tmpfolder=TMPFOLDER"
for /f "tokens=*" %%D in ('dir /b /a:d "*"') do (
for /f "tokens=*" %%E in ('dir /b /a:d "%%D\*" ^| findstr /x /c:"%tmpfolder%"') do (
rem echo Found temp folder: "%%D\%%E"
for /f "tokens=*" %%F in ('dir /b /a:d "%%D\%%E\*"') do (
rem echo Subfolder: "%%F"
set "curdate=!date!"
set "dirdate="
echo GETDATE
call :getdate dirdate "%%D\%%E\%%F"
set "dirdate=!dirdate:~-4!!dirdate:~3,2!!dirdate:~0,2!"
set "curdate=!curdate:~-4!!curdate:~3,2!!curdate:~0,2!"
rem echo dirdate: "!dirdate!"
rem echo curdate: "!curdate!"
rem echo.
if [!dirdate!] LSS [!curdate!] (
echo rmdir /s /q "%%D\%%E\%%F"
)
)
)
)
goto :EOF
:getdate
rem call: getdate date(dstParam) folder(srcParam)
for /f "skip=5 tokens=1 delims= " %%A in ('dir /a:d /o:d /t:c "%~2"') do (
set "%~1=%%A"
goto :EOF
)
Command reference links from ss64.com:
DelayedExpansion
set
for /f
dir
findstr
if
call
goto
rem
Although an answer has already been accepted, I have decided to post this untested idea as an alternative:
#Echo Off
SetLocal EnableDelayedExpansion
For /F "Delims=" %%A In ('WMIC OS Get LocalDateTime') Do For %%B In (%%~nA
) Do Set "TD=%%B" & Set "TD=!TD:~,8!"
For /D /R "ROOTFOLDER" %%A In ("TMPFOLD?R") Do If /I "%%~nxA"=="TMPFOLDER" (
Set "FP=%%~pA" & Set "FP=!FP:\=\\!"
WMIC FSDir Where "Path='!FP!' And FileName='TMPFOLDER'" Get CreationDate^
|FindStr/B "%TD%">Nul||Echo=RD/S/Q "%%A")
Timeout -1
You may need to change ROOTFOLDER and all instances of TMPFOLDER as necessary, remembering to use a ? to replace one of the characters in the first instance of TMPFOLDER.
If the output appears to be correct, remove the last line and Echo= from the line above it.

How to check out with Batch , if a folder contains a .txt file and then copy the folder into an other location?

I would like to make a script with Batch. I want from this script to check it out, If a folder contains a file, "list.txt", and if it is in the folder i want to make a copy in an other location. I wrote some lines of code but it's not working. Any ideas?
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
:loop
for /f %%i in ('dir "C:\Users\ntosis\Desktop\Draft" /ad /o:d /s /b') do (
SET a=%%i
for /R %%a %%t in (*.txt) do if "%%~nxt"=="list.txt" SET p=%%~dpnxt
echo !p!
IF DEFINED %p% ( robocopy C:\Users\ntosis\Desktop\Draft\%a% C:\Users\ntosis\Desktop\Copied\%a% /MOVE /E )
)
echo Folder is empty or does not exist
timeout /t 15
goto loop
The problem in this moment is that the second loop does not the check right.
How about this:
for /f %%i in ('dir "C:\Users\ntosis\Desktop\Draft" /ad /o:d /s /b') do (
IF EXIST "%%i\list.txt" (
robocopy %%i C:\Users\ntosis\Desktop\Copied\ /MOVE /E
)
)
#echo off
setlocal enableextensions disabledelayedexpansion
set "source=C:\Users\ntosis\Desktop\Draft"
set "target=C:\Users\ntosis\Desktop\Copied"
for /l %%t in (0) do (
set "found="
for /d /r "%source%" %%a in (list.txt) do if exist "%%a" (
for %%b in ("%%~dpa.") do (
echo Found "%%a"
robocopy "%%~dpa." "%target%\%%~nxb" /move /e
)
set "found=1"
)
if not defined found (
echo folder is empty or does not exist
)
timeout /t 15
)

Windows Shell Batch Script to copy the last 10 modified files

I'm trying to create a Script to copy from a Directory the last 10 modified files.
I'm trying with this code:
for /F %%I IN ('DIR *.* /B /A:-D-H /O:-D') do (
copy /Y %%I C:\DestinationDir
)
This code copy ALL of them, how can I stop the "for" after 10th iteration?
====================
Second try to solve this.
I tried splitting it in two scripts, but "exit /b" (or only "exit") finish all the batch process:
FirstScript, the same code but trying to exit after copying the newest file:
for /F %%I IN ('DIR *.* /B /A:-D-H /O:-D') do (
copy /Y %%I C:\DestinationDir
exit /b
)
SecondScript, that loops 10 times calling the FirstScript:
for /l %x in (1, 1, 10) do (
FirstScript.bat
)
Here is a variant that works without delayed expansion and without using FIND or FINDSTR. I conditionally exit the loop when I intentionally divide by zero.
set cnt=10
for /f "eol=: delims=" %%F in ('dir /o-d /a-d-h /b') do (
copy /y "%%F" c:\destinationDir
2>nul set /a 1/(cnt-=1) || goto :break
)
:break
for /f "tokens=1,* delims=:" %%a in ('dir /o-d /a-d-h /b * ^| findstr /n "^"') do (
if %%a gtr 10 goto done
copy /y "%%b" c:\destinationDir
)
:done
Try this:
#echo off
setlocal enabledelayedexpansion
set cnt=0
for /f "tokens=1,2* delims=[]" %%b in (
'dir /b /a-d-h /o-d^|find /n /v ""') do (
set /a cnt+=1
if !cnt! LEQ 10 echo copy /y "%%c" "c:\DestinationDir"
)
remove the echo when you see desired results.

Batch script to loop over files while renaming them

I can use this to loop over files:
for %%a in ("%directory%\*.%extension%") do (
echo FILE: %%~fa
)
goto :eof
What if I also rename the files, like this (:rename is a subroutine that renames the files):
for %%a in ("%directory%\*.%extension%") do (
echo FILE: %%~fa
call :rename "%%~fa"
)
goto :eof
In that case, some of the files are renamed (and echoed) two or even three times. I think it's because after they are renamed, in some cases they are regarded as new files that also need to be looped through. However, this does not happen with all the renamed files.
How can I overcome this? I want every file to be renamed only once.
Solution:
:: remove quotes:
:: http://www.dostips.com/?t=Snippets.TrimQuotes
for /f "useback tokens=*" %%a in ('%extension%') do set extension=%%~a
for /f "useback tokens=*" %%a in ('%directory%') do set directory=%%~a
for /f "delims=" %%a in ('dir /b /a-d "%directory%\*.%extension%" ^| sort /r') do (
echo FILE: %directory%\%%a
call :renamingSubroutine "%directory%\%%a"
)
goto :eof
OR:
:: remove quotes:
:: http://www.dostips.com/?t=Snippets.TrimQuotes
for /f "useback tokens=*" %%a in ('%extension%') do set extension=%%~a
for /f "useback tokens=*" %%a in ('%directory%') do set directory=%%~a
for /f "delims=" %%a in ('dir /b /a-d /s /on "%directory%\*.%extension%"') do (
echo FILE: %%~fa
call :renamingSubroutine "%%~fa"
)
goto :eof
try this:
for /f "delims=" %%a in ('dir /b /a-d /s "%directory%\*.%extension%"^|sort /r') do (
echo FILE: %%~fa
call :rename "%%~fa"
)
goto :eof
BTW you shouldn't give batch functions the names of cmd commands (rename).

Resources