setlocal
set Folder=C:\test\
set FileMask=*.*
set OldestFile=
for /f "delims=" %%a in ('dir /b /o:d "%Folder%\%FileMask%" 2^>NUL') do (
set OldestFile=%%a
goto Break
)
:Break
if "%OldestFile%"=="" (
echo No files found in '%Folder%' matching '%FileMask%'!
) else (
echo del "%Folder%\%OldestFile%"
)
pause
Here I delete the oldest file (the file in the folder or the directory in the folder). How to delete the oldest file from the files in the folder and subfolders? It is necessary that the subfolders be checked.
#echo off
setlocal enableextensions disabledelayedexpansion
set "folder=C:\test\"
set "fileMask=*.*"
set "oldestFile="
for %%f in ("%folder%\.") do for /f "tokens=2,*" %%a in ('
robocopy "%%~ff" "%%~ff" %fileMask% /njh /njs /nc /ns /l /is /ndl /ts /s
^| 2^>nul sort
^| find ":"
') do set "oldestFile=%%b" & goto :done
:done
echo "%oldestFile%"
This uses robocopy to list /l the files with time stamp in yyyy/mm/dd hh:nn:ss format, sort the list so the oldest file is the first and once the information of the first file has been retrieved, show it.
Related
There are multiple zipped files say zip1,zip2 etc. Each zip file has multiple files in it. How do we create a batch file that only shows the number of files in the specific folder as
zip1 : 524 files
zip2 : 322 files
the code I made runs on other folders but not on zip files
#ECHO OFF
FOR /D %%D IN ("folderpath\*") DO (
FOR /F %%K IN ('DIR /A-D "%%D" 2^>NUL ^| FIND "File(s)" ^|^| ECHO 0') DO (
ECHO %%D: %%K
)
)
Here's a subroutine that uses zipjs.bat and counts the files within a zip file (it does not require external binaries):
#echo off
:countFilesInZip file.zip [out]
setlocal
set "count=0"
for /f "skip=1 tokens=* delims=" %%a in ('
call zipjs.bat list -flat yes -source "%~f1"^|
findstr /e /v "\\"
') do (
set /a count=count+1
)
::echo %count%
endlocal & if "%~2" EQU "" (
echo %count%
) else (
set "%~2=%count%"
)
goto :eof
to use it:
call :countFilesInZip "c:\zipfile.zip" count
echo %count%
I have files named file.txt in multiple subfolders in my folder. I want to get the path of the latest file.txt
FOR /r %%i IN ('DIR file.txt /B /O:-D') DO SET a=%%i
echo Most recent subfolder: %a%
gives latest created folder having file.txt whereas I want the folder which has latest file.txt
#echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=1,2,*" %%a in ('
robocopy . . file.txt /l /nocopy /is /s /nc /ns /ts /ndl /njh /njs
^| sort /r 2^> nul
^| cmd /v /q /c "set /p .=&echo(^!.^!"
') do (
echo File found : %%c
echo File timestamp (UTC^) : %%a %%b
echo Folder of file : %%~dpc
)
This will use the robocopy command to enumerate all the file.txt files under the current active directory, without copying anything but generating a list of all matching files with a yyyy/mm/dd hh:nn:ss utc timestamp. Then the list is sorted on the timestamp in descending order and only the first line in the output readed and echoed to be processed by the for /f tokenizer and retrieve the date, time and file with full path.
If only the folder is required and the list of files is not very large, a simplified version could be
#echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=1,2,*" %%a in ('
robocopy . . file.txt /l /nocopy /is /s /nc /ns /ts /ndl /njh /njs
^| sort /r
') do set "lastFolder=%%~dpc" & goto :done
:done
echo Last folder : %lastFolder%
Almost the same, but instead of including a filter in the list generation to only retrieve the first line (required if the list of files is very large), here the for /f will retrieve the full list but after the first element is processed we jump out of the loop to the indicated label.
I have a directory that has a 10 sub-directories. Each of these holds different .bak files. I'm trying to create a script that will check to see if X number of files are there and if the number of files exceeds X, it deletes the oldest file. In other words, I want 20 iterations of a .bak file. When the 21st one shows up, I want the batch file to delete the oldest one.
Is this possible?
If so, can I create a single script that looks in all the sub-directories?
Thanks in advance.
Two options included. The first one will leave %maxFiles% bak files under each of the folders. The second one (windows Vista or later OS is required as robocopy is used to obtain the sorted list of files) will leave %maxFiles% in total
#echo off
setlocal enableextensions disabledelayedexpansion
set "rootFolder=%cd%"
set "maxFiles=20"
rem Option 1 - Keep %maxFiles% inside each of the subfolders
for /d /r "%rootFolder%" %%z in (*) do for /f "skip=%maxFiles% delims=" %%a in (
'dir /tc /o-d /a-d /b "%%~fz\*.bak" 2^>nul'
) do echo del "%%~fz\%%~nxa"
echo ------------------------------
rem Option 2 - Keep %maxFiles% in total under all the subfolders
for /f "skip=%maxFiles% tokens=2,*" %%a in ('
robocopy "%rootFolder%" "%rootFolder%" *.bak /l /nocopy /is /s /njh /njs /ndl /nc /ns /ts
^| findstr /v /r /e /i /c:"%rootFolder:\=\\%\\[^\\]*"
^| sort /r
') do echo del "%%b"
del commands are only echoed to console. If the output is correct, remove the echo command to remove the files
assumes that you want to check the number of files from the parent directory.Can be done also for each sub-directory.
#echo off
setlocal
set "max_number_files=20"
set "parrent_dir=c:\whatever_you_need"
set "extension=.bak"
pushd "%parrent_dir%"
set "count=0"
setlocal enableDelayedExpansion
for /f "delims=" %%a in ('dir /s /b /a:-d /o:-d /t:c *%extension%') do (
set /a count=count+1
if 1!count! GTR 1!max_number_files! (
rem --- remove the echo to activate deletion
echo del /q /f "%%~a"
)
)
popd
endlocal
endlocal
This will check each folder under d:\base\folder and if there are more than 20 *.bak files it will remove the oldest ones so only 20 *.bak file remain, in each folder.
Test it on some sample folders.
#echo off
for /d /r "d:\base\folder" %%a in (*) do (
pushd "%%a"
for /f "skip=20 delims=" %%b in ('dir /b /a-d /o:-d *.bak ') do del "%%b"
popd
)
Need your help
I need create a batch file (command prompt) to
⁃ Show a list of folders and sub folders
⁃ within them are exe files
⁃ Only show the 2 most up to date exe files
⁃ display specific folders not all
And export information in a txt file
I'm using XP if that helps
update
I have the below commands
first one works and orders by most recent file, but doesn't give me time and date
second shows time and date but doesn't order by most recent
#ECHO OFF
setlocal EnableDelayedExpansion
set j=0
Echo Test
echo\
FOR /f "delims=" %%i IN ('dir C:\test\ /o-n-d /b') DO (
echo %%i
set /A j=j+1
if !j! geq 2 (
goto :end1
)
)
:end1
#ECHO OFF
setlocal EnableDelayedExpansion
set j=0
echo\
Echo Test
echo\
FOR /f "delims=" %%i IN ('forfiles /p C:\testmove /s /m *.* /C "cmd /c echo #file #fdate #ftime" ') DO (
echo %%i
set /A j=j+1
if !j! geq 2 (
goto :end2
)
)
:end2
pause
#ECHO OFF
SETLOCAL enabledelayedexpansion
SET "sourcedir=U:\sourcedir"
SET "lastdir="
(
FOR /f "delims=" %%a IN (
'dir /s /b /a-d "%sourcedir%\*.exe" '
) DO (
IF "%%~dpa" neq "!lastdir!" (
SET "lastdir=%%~dpa"
SET /a count=0
FOR /f "delims=" %%i IN ('dir /s /b /a-d /o:d "%%~dpa\*.exe"') DO IF !count! lss 2 (
SET /a count+=1
ECHO %%~ti %%~fi
)
)
)
)>newfile.txt
GOTO :EOF
Produces newfile.txt. You would need to set your required directory name in sourcedir. I showed the data as date/time fullfilename because fullfilename is of variable-length whereas date and time are fixed. Might have been easier if you'd shown us the format you expect - saves guesswork and revisions.
To show the two most recently modified files, change .../b /a-d /o:d "%%~... to .../b /a-d /o:-d "%%~... (note - between the o: and d)
Uses Robocopy to show the two latest modified .exe files in the current folder tree
It also displays the UTC date and time of the two files.
#echo off
setlocal enabledelayedexpansion
set "folder=%cd%"
set c=0
for /f "tokens=1,2,*" %%a in (
'robocopy "%folder%" "%folder%" "*.exe" /s /is /nocopy /nc /ns /ts /fp /np /ndl /njh /njs /xjd /r:0 /w:0 /l ^| sort /r '
) do echo "%%a %%b" - "%%c" & set /a c+=1 & if !c! EQU 2 goto :done
:done
pause
The batch file below recursively echos files and folders while adding some simple formatting, such as indenting to show the recursion depth, adding "/ " before folder names, "*" before certain files, and skipping folders named "Archive". It works great except that files and folders are sorted randomly, rather than alphabetically. How could this be changed to sort both files and folders alphabetically?
#echo off
setlocal disableDelayedExpansion
pushd %1
set "tab= "
set "indent="
call :run
exit /b
:run
REM echo the root folder name
for %%F in (.) do echo %%~fF
echo ------------------------------------------------------------------
set "folderBullet=\"
set "fileBullet=*"
:listFolder
setlocal
REM echo the files in the folder
for %%F in (*.txt *.pdf *.doc* *.xls*) do echo %indent%%fileBullet% %%F - %%~tF
REM loop through the folders
for /d %%F in (*) do (
REM skip "Archive" folder
if /i not "%%F"=="Archive" (
REM if in "Issued" folder change the file bullet
if /i "%%F"=="Issued" set "fileBullet= "
echo %indent%%folderBullet% %%F
pushd "%%F"
set "indent=%indent%%tab%"
call :listFolder
REM if leaving "Issued folder change fileBullet
if /i "%%F"=="Issued" set "fileBullet=*"
popd
))
exit /b
Very little change required. Convert FOR loops to FOR /F running sorted DIR commands. The /A-D option lists files only, and /AD lists directories only.
This version sorts files by name
#echo off
setlocal disableDelayedExpansion
pushd %1
set "tab= "
set "indent="
call :run
exit /b
:run
REM echo the root folder name
for %%F in (.) do echo %%~fF
echo ------------------------------------------------------------------
set "folderBullet=\"
set "fileBullet=*"
:listFolder
setlocal
REM echo the files in the folder
for /f "eol=: delims=" %%F in (
'dir /b /a-d /one *.txt *.pdf *.doc* *.xls* 2^>nul'
) do echo %indent%%fileBullet% %%F - %%~tF
REM loop through the folders
for /f "eol=: delims=" %%F in ('dir /b /ad /one 2^>nul') do (
REM skip "Archive" folder
if /i not "%%F"=="Archive" (
REM if in "Issued" folder change the file bullet
if /i "%%F"=="Issued" set "fileBullet= "
echo %indent%%folderBullet% %%F
pushd "%%F"
set "indent=%indent%%tab%"
call :listFolder
REM if leaving "Issued folder change fileBullet
if /i "%%F"=="Issued" set "fileBullet=*"
popd
))
exit /b
To sort by extension first, then by name, simply change /ONE to /OEN.
Try changing your for /d loop from
for /d %%F in (*) do
to
for /f "delims=" %%F in ('dir /b /o:n *.') do
and see whether that makes a difference. Actually, ordering by name is the default behavior for dir, so you could probably get away with
for /f "delims=" %%F in ('dir /b *.') do
If some of your directory names have dots in them, you'll need to change it a little.
for /f "delims=" %%F in ('dir /b') do (
rem Is this a directory?
if exist "%%F\" (
rem do your worst....
)
)