find path of latest file using batch command - batch-file

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.

Related

Delete the oldest file from the files in the folder and subfolders

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.

How to find and copy previous latest file created larger than a custom size?

I wrote a batch file which should find and copy the latest build file bigger than a 3.5 GB.
set source=D:\src
set tmp_dir="D:\tmp"
set "file="
for /f "delims=|" %%a in ('
dir /b /o-d "%source%\*.zip" 2^>nul
^| cmd /q /v /c"set /p .=&if defined . (echo(!.!)"
') do set "file=%%a"
echo %file%
robocopy %source% %tmp_dir% %file% /MT:16 /X /MIN:3500000000 /XO /V /TS /FFT /R:3 /W:10 /ETA
My problem is what happening when the latest file is smaller than 3.5 GB. In this case is need to copy the next file larger than 3.5 GB.
You almost have it. Instead of using the dir command to retrieve the initial list of files, we can use robocopy to get a list (/l) of files in the source folder with the required minimum size (/min). This list should not include job header, job footer, nor directory list (/njh, /njf, /ndl). For each file we don't need the class of the file (/nc) or the size of the file (/ns), but we want the time stamp (/ts) of the files to sort the list on this field.
This will leave a sorted list of files with the newer file matching the conditions as the first in the list.
#echo off
setlocal enableextensions disabledelayedexpansion
set "source=D:\src"
set "tmp_dir=D:\tmp"
set "file="
for /f "tokens=2,*" %%a in ('
robocopy "%source%" . *.zip /l /xx /is /njh /njs /ndl /nc /ns /ts /min:350000000000
^| sort /r
^| cmd /q /v /c"set /p .=&if defined . (echo(!.!)"
') do set "file=%%~nxb"
echo(%file%
if defined file (
robocopy "%source%" "%tmp_dir%" "%file%" /MT:16 /X /XO /V /TS /FFT /R:3 /W:10 /ETA
)
You can get the size of a file in bit using the following line
for /f "usebackq" %%a in ('%file%') d set filesize=%%~za
Add
set /a filesize+=0
to make sure it is treated like a numeric variable.
Then use an if-statement to check if filesize exceeds 3500000000 byte -> 3.5 GB.
if filesize LSS 3500000000 (
echo not 3.5 GB
) ELSE (
echo bigger than 3.5 GB
)
Adding other echoes is up to you.

Find last modified file in all subfolders

I need a Windows batch code to find the last modified file among all the files in all the subfolders of a specific folder.
It doesn't seem to be so simple as it appears.
Some files could have been modified in the same minute, but in different seconds. I need only the lastest one.
#echo on
setlocal enableextensions disabledelayedexpansion
set "root=c:\somewhere"
for %%r in ("%root%\.") do for /f "tokens=3,*" %%a in ('
robocopy "%%~fr." "%%~fr." /l /nocopy /s /is /njh /njs /ndl /nc /ns /ts
^| sort /r
^| findstr /n "^"
^| findstr /l /b /c:"1:"
') do echo %%b
This code uses robocopy (native for Vista and later OS versions, downloadable from Microsoft for XP or 2003) to obtain a list of files with timestamp in yyyy-mm-dd hh:nn:ss format, that is sorted in decreasing order and then only the first line (that is, the newer file) is retrieved.

File Retention Script

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
)

Finding the newest file in a directory

I am a complete novice in batch programming but have found some great scripts in here that I tried modifying. I need the info on the last file modified in a directory. The script below gives me a file with info about file name and modification time. It searches through subdirectories too but seems to get stuck in a subdirectory instead of finding the newer file in the parent directory. I am not sure what could be wrong (as I only partly understand the code). Any suggestions from you smart guys in here?
Thanks in advance!
#echo off
setlocal
set srcDir=C:\Test
set lastmod=
pushd "%srcDir%"
for /f "tokens=*" %%a in ('dir *. * /b /od /s /a-d 2^>NUL') do set lastmod=%%a
if "%lastmod%"=="" echo Could not locate files.&goto :eof
for /d %%a in ("%lastmod%") do echo "%lastmod%", Modified date: %%~ta>"C:\Test\Details.txt"
This uses robocopy so it will only work on windows Vista and later. For it to work on XP you will need to get a copy of robocopy from a later OS or from resource kit.
No copy operation will really be made, but it will allow to retrieve a recursive file list with an adequated file stamp that can be sorted to find latest file.
#echo off
setlocal enableextensions disabledelayedexpansion
set "folder=%cd%"
for /f "tokens=2,*" %%a in (
'robocopy "%folder%" "%folder%" "*" /s /is /nocopy /nc /ns /ts /fp /np /ndl /njh /njs /xjd /r:0 /w:0 /l ^| sort /r '
) do ( set "latest=%%b" & goto :done )
:done
for %%f in ("%latest%") do echo(%%~tf %%~ff

Resources