Recursively Iterating through Directories in Batch - batch-file

Here's the situation:
I have a folder with lots of sub-folders with pdf files. I want to make a batch script that goes through each sub-folder and zip the pdf files if there are over 100 of them (using 7Zip, not asking for help with that part).
This is my first time dealing with windows batch scripting and I am extremely discourage. I have spent hours on Google and I don't think I'm any wiser on the subject. I have found a lot of reference material and example code but not a whole lot of word by word breakdown on examples. I find the syntax to be extremely user unfriendly.
Anyways here's what I've got:
#echo off
for /r %%A in (.) do (
set pdfCount = "Code that gets the total number of pdf files in current directory, something like dir *.pdf?"
if pdfCount GEQ 100 (
set beginDate = "Code that gets the date of the oldest pdf, use in the zip file name"
set endDate = "Code that gets the date of the newest pdf, use in the zip file name"
"Use a 7Zip command to zip the files, I am not asking for help with this code"
DEL *.pdf
echo %pdfcount% files zipped in "Code for current directory"
)
)
pause
My understanding is that "for /r %%A in (.) do ()" is supposed to do execute the code in every sub-directory.

This script is locale dependent, meaning it depends on the way dates and times are formatted on your machine. My machine uses mm/dd/yyyy hh:mm am format. The script will create zip files with names in the form of PDF yyyy_mm_dd yyyy_mm_dd.7z.
#echo off
setlocal disableDelayedExpansion
for /r /d %%P in (*) do (
set "beg="
set /a cnt=0
pushd "%%P"
for /f "eol=: delims=" %%F in ('dir /b /a-d /od *.pdf 2^>nul') do (
set /a cnt+=1
set "end=%%~tF"
if not defined beg set "beg=%%~tF"
)
setlocal enableDelayedExpansion
if !cnt! gtr 100 (
for /f "tokens=1-6 delims=/ " %%A in ("!beg:~0,10! !end!") do (
7zip a "PDF %%C_%%A_%%B %%F_%%D_%%E.7z" *.pdf
del *.pdf
)
)
endlocal
popd
)

This may work. It's not destructive and atm just echoes the 7zip and parameters to the screen.
#echo off
for /f "delims=" %%a in ('dir /b /ad /s') do (
pushd "%%a"
for /f %%b in ('dir *.pdf /b ^|find /c /v "" ') do (
if %%b GTR 100 echo 7zip a "%%~nxa.7z" "*.pdf"
)
popd
)
It takes all the folders in the current directory tree, pushes the directory on the stack to make it current, uses dir and find to count the PDF files, and if the result is greater than 100 it will echo the line to the console. And popd pops the directory off the stack again. The 7z files will be created in the folder with the PDF files and they get the folders name.7z , unless you specify a location for them.

Related

Using batch file to list files created or modified in the last 7days

I'm trying to create a batch file that will look across a folder and its subfolders and list any file that has been created or modified within say the last 7 days. I only want to know files that meet the condition, not folders.
I've played around with DIR command, but whatever I do, it always seems to list everything.
I found this piece of code in Stackoverflow from 2017 which looked promising (I played around with the DIR switches), but it doesn't seem to create any output.
My knowledge of batch files and their commands is pretty limited. Running Windows 10.
TIA
Nigel
#echo off
setlocal EnableDelayedExpansion
echo Input the date(dd/mm/yyyy):
set /p compDate=
for /F "tokens=1-3 delims=/" %%a in ("%compDate%") do set compDate=%%c%%b%%a
echo Input the directory:
set /p directory=
SET Exit=%UserProfile%\Desktop\test.txt
pushd "%directory%"
(for /F "tokens=1-5*" %%a in ('dir /s /od /tc /a-d') do (
set "fileDate=%%a"
if "!fileDate:~2,1!!fileDate:~5,1!" equ "//" (
for /F "tokens=1-3 delims=/" %%x in ("!fileDate!") do set fileDate=%%z%%y%%x
if !fileDate! geq %compDate% (
set "fileSize= %%e"
echo %%a %%b %%c %%d !fileSize:~-16! %%f
)
)
)) > %Exit%
popd
If I misunderstood you, you can go deeper into the topic here
forfiles /P FOLDER_PATH\ /S /D -7

Speed up Batch file processing, moving file to folder of same name

I need some help moving files into folders of the same name. I have a batch file that works but it is very slow. I'm moving approximately 3300 .xlsx files into folders with like names. Here is what I have thus far:
#echo off
setlocal EnableDelayedExpansion
pushd "C:\New folder"
FOR %%G IN (*.xlsx) DO (
FOR /F "tokens=1 delims= " %%a IN ("%%G") do (
set "outFolder=%%a "
for /D %%i in (*.*) do (
for /F "tokens=1 delims= " %%b IN ("%%i") do (
if "%%a"=="%%b" set "outFolder=%%i"
)
)
if not exist "!outfolder!" md "!outfolder!"
move "%%G" "!outfolder!"
)
)
popd
pause
Again this works but is slow. This code moves the files to folder and if folder doesn't exist it creates it.
I have found this code and it works to a point. The following code does not seem to recognize the folders that already exist and instead creates a folder even though one already exists. Example: I have file 123456 Action List.xlsx that I would like to go to folder 123456 Health Center. The first code will accomodate that but is extremely slow and gets slower as it goes along. Here is the second code:
#echo off &setlocal
for /f "delims=" %%i in ('dir /b /a-d *.xlsx') do (
set "filename1=%%~i"
setlocal enabledelayedexpansion
set "folder1=!filename1:~0,6!"
mkdir "!folder1!" 2>nul
move "!filename1!" "!folder1!" >nul
endlocal
)
Any help is appreciated.
#Squashman - I'll try to explain a little better...
123456 Action List.xlsx
123456 Reportcard.xlsx
123456 CHCUP.xlsx
123456 Combo3.xlsx
123457 Action List.xlsx
123457 Reportcard.xlsx
123457 CHCUP.xlsx
123457 Combo3.xlsx
Each month I end up with ~3300 files like this after running various macros. I have folders like "123456 Health Center" and "123457 MLK Center" already set up. What I'm trying to do is move all of those .xlsx files into the corresponding folder. That first code set works but like I said its slow. What its doing is looking to see if there are corresponding file and folder names based on first 6 characters. If there is it moves the file to that folder.
The second code is MUCH faster but it doesnt like the second part of the folder name i.e. "Health Center or MLK Center" from my examples and it then creates its own file with just the number portion i.e. 123456 or 123457 from my example.
Does that help?
Save this script as test.bat in a folder with other .bat files, and run from open Cmd Prompt. Replace dir value with the path to your folder with XLSX files. The script assumes, target folders in which the files are sorted are created in the dir folder. Let me know if any errors.
#echo off
setlocal enabledelayedexpansion
set "dir=C:\XLSX_Folder"
pushd "%dir%"
for /f "tokens=*" %%I in ('dir /b /a:-d "*.xlsx"') do (
if not exist "%%~nI" md "%%~nI" 2>nul
move "%%I" "%%~nI" >nul )
popd
exit /b

Batch Script: For Loop with Two commands

I have been working on a batch script to loop through a folder and produce a list of the files sorted by when they were last modified. Right now it works as expected, but it does not search through sub-folders, below is my code:
echo Last executed on %date% at %time% > report.csv
echo. >> report.csv
FOR /F "TOKENS=1-4,* SKIP=4" %%a IN ('DIR /O-D /TW') DO (
IF exist %%e (
IF NOT %%e==.. (
IF NOT %%e==. (
echo %%e >> report.csv
echo %%a %%b >> report.csv
)
)
)
)
:Start
CScript modifyexcelGood.vbs
:End
goto :eof
Ignore those if statements, they are just there to prevent incorrect filenames I was getting. I know the /R command is for searching through subfolders, but it appears I cannot use both /R and /F, or perhaps I am wrong? I feel like there is a simple solution but I have not been able to find it.
Thanks
EDIT
To clarify, the batch file sorts all the files in a directory by date modified and throws the file name and date of each file found in an excel sheet(In sorted order). It then starts a VB script that edits the sheet to make it look nice. The Vbs and bat scripts must be together but they are meant to be used in any directory. They are meant to help clean out large directories that have old files sitting around. (It will eventually delete the old files too once I know this works 100%.)
I can put these in any directory and it works fine, I just need it to hit the files in any subfolders as well.
So how can I edit my code to make it check if %%e is a directory and if so run the loop on that directory as well?
Thanks
I am afraid your request is not clear. However, the line below list the files in current folder and all subfolders beneath, one line per file, and sort all files by last modified date, newer files first.
(for /F "delims=" %%a in ('dir /T:W /S /B') do echo %%~Ta %%a) | sort /R > report.csv
If you have any doubt about dir command switches (like /B), type dir /?.
to really sort the files by date, you can temporarily modify the short date format to yyyy.MM.dd
#echo off
setlocal EnableDelayedExpansion
REM get current short date format:
for /f "tokens=2,*" %%a in ('reg query "HKCU\Control Panel\International" /v sShortDate') do set orig-format=%%b
REM set short format to yyyy.MM.dd:
reg add "HKCU\Control Panel\International" /v sShortDate /d "yyyy.MM.dd" /f >nul
(for /F "delims=" %%a in ('dir /a-d /T:W /S /B') do #echo %%~Ta %%a)|sort /r >report.csv
REM set short date format back to original settings:
reg add "HKCU\Control Panel\International" /v sShortDate /d "%orig-format%" /f >nul
I stole the line from Aacini with the following changes:
- added /a-d to dir to exclude folders
- added # in front of echo which removes a lot of empty lines in the resulting file.
and put the neccessary changes for the date format around it.

Delete all files except filenames with specific string

I have 1000's of files like TOP_QUERIES-abc.com.au.csv,TOP_QUERIES-www.abc.com.au.csv, TOP_QUERIES-m.lmn.com.au.csv, TOP_QUERIES-blog.com.au.csvand get-files.php
Is it possible to delete all the .csv files from a folder except for files starting with blog. ,m. , www, and .php from the folder?
I know its possible in php but how can I achieve in batch file?
#ECHO OFF
SETLOCAL
SET "targetdir=U:\destdir"
SET "exclude=blog. m. www."
FOR /f "delims=" %%a IN (
'dir /b /a-d "%targetdir%\*.csv" '
) DO (
ECHO %%a | findstr /B /L "%exclude%" >NUL
IF ERRORLEVEL 1 ECHO(DEL "%targetdir%\%%a"
)
GOTO :EOF
This should get the task done for you. You would need to change the setting of targetdir to suit your circumstances.
The required DEL commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(DEL to DEL to actually delete the files.
The .php files are excluded because they don't match the *.csv filename - or did you want to not-delete files starting .php? If so, simply add .php into the exclude variable...
Revision for efficiency:
#ECHO OFF
SETLOCAL
SET "targetdir=U:\destdir"
SET "exclude=blog. m. www."
FOR /f "delims=" %%a IN (
'dir /b /a-d "%targetdir%\*.csv" ^| findstr /B /L "%exclude%"'
) DO (ECHO(DEL "%targetdir%\%%a"
)
GOTO :EOF

create folders based on string in file name

I need a batch file to create a process for a list of files in a directory.
The filename structure is, for example: 00000_AAA_132144_2012021.txt
I need the batch to:
1 - Create a folder name based on the numbers after the second underscore, as this is the only constant in the naming.
2 - Move the file into the new folder.
In the example of the above the batch would create a folder called 132144 and then move the file 00000_AAA_132144_2012021.txt into the folder
For a similar requirement I used the script Endoro created for me (below). Is it possible to modify this to meet my requirement?
#echo off &setlocal
for /f "delims=" %%i in ('dir /b /a-d *.PDF') do (
set "filename1=%%~i"
setlocal enabledelayedexpansion
set "folder1=!filename1:~11,6!"
mkdir "!folder1!" 2>nul
move "!filename1!" "!folder1!"
endlocal
)
If you know that the filenames will be the same length, you can do the following to get the numbers after the second underscore -
set filename=00000_AAA_132144_2012021.txt
set dirname=%filename:~10,6%
If the spacing may vary - you can do the following -
for /f "delims=_ tokens=3" %%a in ('echo %filename%') do set dirname=%%a
And yes, the script written for you seems to do essentially the same thing as what you're asking - I've edited it to do what you've asked -
#echo off
setlocal enabledelayedexpansion
for /f %%i in ('dir /b /a-d *.txt') do (
set "filename=%%~i"
for /f "delims=_ tokens=3" %%a in ('echo !filename!') do set folder=%%a
mkdir "!folder!" 2>nul
move "!filename!" "!folder!"
)
This will move all *.txt documents to a folder created based on the third section of the text files name. Note that this will cause problems if you have .txt documents in the directory that do not follow the same naming standard.
#ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
SET "destdir=c:\destdir"
FOR /f "delims=" %%a IN ('dir /b /a-d "%sourcedir%\*_*_*_*.txt" ') DO (
FOR /f "tokens=3delims=_" %%m IN ("%%a") DO (
ECHO MD "%destdir%\%%m"
ECHO MOVE "%sourcedir%\%%a" "%destdir%\%%m\"
)
)
GOTO :EOF
Endoro's routine selects .pdf files, you've specified .txt
Find filenames matching the mask, find the third _-separated token in the name, make that directory and then move the file.
The required commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO MD to MD to actually create the directories and change ECHO MOVE to MOVE to actually move the files.
Append 2>nul to suppress error messages (eg. when the directory already exists)
Append >nul to suppress report messages (eg. 1 file moved)

Resources