Batch Script: For Loop with Two commands - batch-file

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.

Related

Batch - Returning full path from a dir /b

I am traversing folders on a drive, collecting file names with specific extensions, and building a string which is later used in a command line switch. When I find a qualifying file I need to know its full path as this is what is required by the command line. I currently use "%~dp0%%a\%%b" to build the full path, but I can see that may have limitations later on when the batch becomes more complex (e.g. it digs deeper into sub folders). I am hoping there is a way to replace "%~dp0%%a\%%b" with the path to the located file. Thank you:
#ECHO OFF
for /f "usebackq tokens=*" %%a in (`dir /b /a:d`) do (
pushd %%a
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%b in ('dir /b "*.E01" "*.L01" "*.AD1" 2^>nul') do (
SET EVIDENCE_STR=!EVIDENCE_STR! /e:"%~dp0%%a\%%b"
)
IF DEFINED EVIDENCE_STR (
ECHO !EVIDENCE_STR!
) ELSE (
ECHO No evidence files located in: %%a
)
endlocal
SET EVIDENCE_STR=
popd
)
PAUSE
Why do you need to create 2 loops, each running a dir command to find files? Why not just do for /R loop? Here is an example:
#echo off
set "files=*.E01 *.L01 *.AD"
for /R %%a in (%files%) do echo %%a
Simply use "Sub"-Option: /S of the DIR-Command:
Dir /B /S C:\*.jpg
cause it is that equivalent to:
#echo off
set "DirPath=C:\"
set "files=*.jpg"
for /R %DirPath% %%a in (%files%) do echo %%a
and so you should got the same result in each script.
The Problem: If you don't want any deep of SubDirectorys, you've to filter out these and so you may lose time - in both solutions.

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

How do I delete a list of files using a batch script?

I'm new to writing batch files and I need to write one in order to delete a list of files please. I need the batch script to first locate the files (they are all based in different folders in the same drive) and then subsequently delete all of them. Is there a way that I can write a batch script to locate the files in a list and then delete them all automatically?
Apologies for how basic this question is - I am completely unsure how to go about this task!
#echo off
for /f "tokens=*" %%i in (list.txt) do (
for /f "tokens=*" %%j in ('dir /s /b /a-d "c:\%%i"') do echo del "%%j"
)
remove the echo, if the output satisfies you.
get every filename in your list (%%i)
. get every full path (%%j) for this filename (search through the disk) and delete it.
NOTE: this is not fast - searching the whole disk for every single filename needs some time.
If there are many filenames in your list, it may be better to build a complete direcotry-tree only once and write it to a file (dir /s /c /a-d >diskcontent.txt), working with that file instead of searching the disk for every file.
dir-parameters: /s search in all subdirectories, /b use a format that gives you the complete path, /a-d exclude directorynames; c:\ start in the root of drive C:
EDIT
if your list.txt contains spaces (either in the filename or in a given path), you have several options:
pushd "C:\path to\my file"
for /f "tokens=*" %%i in (list.txt) do (
or
for /f "tokens=*" %%i in ('type "C:\path to\my file\list.txt"' ) do (
or
for /f "usebackq tokens=*" %%i in ("C:\path to\my file\list.txt") do (

Batch find certain filenames then use the names in variable

I need help with a script that first finds all files in a directory with a certain string, then uses the filenames in a variable to be used in a script.
So:
Find files and filenames
Saves file?
Start some kind of loop? that changes a variable then executes the
belonging script
Repeat till all filenames have been used.
My code here..
#Echo off
For /r C:\work %%G In (*) Do #Findstr /M /S "string" > filenames.txt %%G
Set Var1=0
For %%G In (*) Do (
Var1=<filenames.txt (???)
script
script
I haven't writen "script" myself and friend help me with it, if you would like to see it do you need to wait until I can get to my other computer at home.
Thanks on beforehand!
Find files and filenames
Saves file
set "search=what I want to find"
(for /f "delims=" %%a in ('dir /a-d /b /s "C:\work" ^| findstr "%search%"') do echo (%%~fa)>filenames.txt
Start some kind of loop? that changes a variable then executes the belonging script
Repeat till all filenames have been used.
for /f "delims=" %%a in (filenames.txt) do (
REM here do something inside the loop
REM until all file names from filenames.txt were processed
)
This is designed to find files in c:\work that match a string, and echo the filenames.
#echo off
cd /d "c:\work"
for %%a in ("*string*") do (
echo "%%a"
)

Recursively Iterating through Directories in Batch

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.

Resources