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"
)
Related
I need to count the number of .txt files in a Windows 10 directory.
I am starting with the following code as a batch-file:
#ECHO OFF
for %%f in (*.*) do echo %%f
Does anyone know how I can do it?
The method will most likely depend upon the rest of the script; but for the question only.
Probably the simplest method would be to use where.exe and find.exe together:
Where .:*.txt 2>Nul|Find /C /V ""
Should you wish to save the count as the value content of a variable, you can use a For /F loop incorporating either where.exe or the Dir command. Please note however that in both a standard For loop, (For %%A In (*.txt)), and when using the Dir command, (Dir *.txt), file extensions beginning with .txt are returned as opposed to those ending with .txt, returned by where.exe. In order to account for this, in my Dir version, I have piped the results through a findstr.exe to ensure that only .txt files are counted:
Where method:
#Echo Off
Set "#=0"
For /F %%A In ('"Where .:*.txt 2>Nul|Find /C /V """')Do Set "#=%%A"
Echo(%#%
Pause
Dir method:
#Echo Off
Set "#=0"
For /F %%A In ('"Dir/B/A-D-L *.txt 2>Nul|FindStr/I "txt$"|Find /C /V """'
)Do Set "#=%%A"
Echo(%#%
Pause
I am attempting to find files to run commands against in a command prompt (batch) script. So far, so good:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /R %%I IN ("*.Marker.txt") DO (
SET MARKER=%%I
SET LOG= ???
ECHO MARKER IS !MARKER! AND LOG IS !LOG!
)
Basically, I want to iterate on a pair of files and execute a command on them (for now just echo). The problem I have is that the log file can be in any directory from where the *.Marker.txt file exists. I can't simply just say 100.Marker.log because that's just the filename, not the full path. Some examples:
C:\Temp\Samples\3A5\100.Marker.txt
C:\Temp\Samples\3A5\9\1\100.Marker.log
C:\Temp\Samples\39B\122.Marker.txt
C:\Temp\Samples\39B\2\5\122.Marker.log
So, not really sure what to do here.
You can use PUSHD/POPD to push/pop the working directory during the script and an inner loop.
FOR /R %%I IN ("*.Marker.txt") DO (
SET DIRECTORY=%%~DPI
SET FILENAME=%%~NI
SET MARKER=%%I
PUSHD !DIRECTORY!
FOR /R %%J IN ("!FILENAME!.log") DO (
SET LOGFILE=%%J
ECHO !MARKER!
ECHO !LOGFILE!
)
POPD
)
Not sure how to find a single value, the FOR technically will run on all matches, but if you say you should only have a single value than the inner loop will only run once per marker file. Maybe there's a more efficient way to search for a single file without using FOR?
If all of your files have the same format (text.Marker.ext), then you can use:
#echo off
setlocal EnableDelayedExpansion
for /R %%A IN ("*.Marker.*") DO (
set MARKER=%%A
for /F "tokens=1 delims=." %%B IN ("%%A") do (
set LOG=%%B
)
echo MARKER IS !MARKER! AND LOG IS !LOG!
)
Please note that I don't generally suggest capital letters in batch file.
We make a loop that loops through all subfolders (for /R) trying to find files containing .Marker. (IN ("*.Marker.*")).
We set the output to a variable (MARKER).
Now, we loop through filename found setting delims to .. This means that: token1.token2.token3. . won't be parsed as a token.
Set result to variable.
#echo off
setlocal enabledelayedexpansion
REM following lines to create test environment
md C:\Temp\Samples\3A5\9\1 2>nul
md C:\Temp\Samples\39B\2\5 2>nul
break>C:\Temp\Samples\3A5\100.Marker.txt
break>C:\Temp\Samples\3A5\9\1\100.Marker.log
break>C:\Temp\Samples\39B\122.Marker.txt
break>C:\Temp\Samples\39B\2\5\122.Marker.log
REM end creating test environment
for /R "C:\Temp\Samples\" %%a in ("*.marker.txt") do (
for /f %%b in ('dir /s/b "%%~dpa\%%~na.log"') do (
ECHO Textfile: %%a Logfile: %%b
)
)
The for /R looks recursively for all matching files (*.marker.txt in C:\Temp\Samples\ and subfolders.
The for /f looks for matching log files below the folder, where the marker.txt is.
Output:
Textfile: C:\Temp\Samples\39B\122.Marker.txt Logfile: C:\temp\Samples\39B\2\5\122.Marker.log
Textfile: C:\Temp\Samples\3A5\100.Marker.txt Logfile: C:\temp\Samples\3A5\9\1\100.Marker.log
Note: this assumes, there is only one matching .log for each .txt and it's within the tree below .txt
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.
Using a batch file I'm trying to generate a list of only folders within a location that contain a certain file type, let's call it *.abc
at the moment I only know how to echo a DIR command output to a file called folder.lst, I would like to expand on that and try to either
a) echo only folders containing the *.abc file type to folder.lst
b) remove references in folder.lst of folders that do not contain the *.abc file type.
I also tried having a FOR loop check each line to see if a *.abc file existed in that location and skip it, if not, but I just could not get that to work, here is an example of what I had.
setlocal enableextensions enabledelayedexpansion
FOR /F "delims=" %%C in (folder.lst) do (
set temp=%%C
if not exist !temp!\*.abc (goto skip) else (goto resume)
:resume
then my actions live here
:skip
)
but I am aware I am doing something wrong here...I just do not know what.
Maybe the /R form of the for command will help:
for /r "basedir" %%a in (.) do if exist "%%~a\*.abc" (
echo %%a contains .abc file(s)
)
The %%a will be the directories you want (with a trailing \., but you should be able to not care or accommodate this).
There are problems with such of the script as you have posted in that you can'y use labels within a block statement. You've also not provided any examples.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "lastdir="
FOR /r "%sourcedir%" %%a IN (*.abc) DO IF "!lastdir!" neq "%%~dpa" (
SET "lastdir=%%~dpa"
ECHO %%~dpa
echo "!lastdir:~0,-1!"
)
GOTO :EOF
Each directory found will be echoed twice - one with the trailing \ and once without.
You would need to change the setting of sourcedir to suit your circumstances.
#echo off
setlocal enableextensions disabledelayedexpansion
set "root=%cd%"
for %%a in ("%root%") do for /f "delims=: tokens=2" %%b in ('
dir /a-d /s "%root%\*.abc" ^| find "\"
') do echo(%%~da%%~pnxb
This executes a recursive dir command searching for the indicated file type under the starting point (change root variable to suit your needs). For each found folder we retrieve the folder from the dir header that precedes the file list (the lines that contain a backslash).
To separate the path from the rest of the information in the line, the colon is used as delimiter. As this will leave the drive out of the retrieved information, an aditional for is used to retrieve the drive from the folder reference.
From the command line:
for /f "delims=" %a in ('dir /s /b *.abc') do echo %~dpa >> folders.lst
In a batch file:
for /f "delims=" %%a in ('dir /s /b *.abc') do echo %%~dpa >> folders.lst
The above commands will place only the folder names containing the *.abc files in folders.lst.
Notes:
% should be replaced by %% when the command is used in a batch file.
The ~dp part of %~dpa expands %a to a drive letter and path only. Remove the d if you don't want the drive letter. The p path includes a trailing \ which may be interpreted as an escape character by some commands.
The above commands start the search in the current directory. To search from the root of the current drive you can do cd \ first.
For more information see FOR /F Loop command: against the results of another command and Parameters.
For example, I will supply a filename and I want the script to search the computer for this file and return the path to a variable. Psuedo call is:
Set pathToMyFile = SomeSearchFunction(myFileToSearchFor.ext)
Thanks
dir /b /s "c:\myFileToSearchFor.ext" will list every occurance of the file within the C: drive, including the full path information.
The file could exist in multiple locations.
This batch command will set a variable to the last found location:
for /f "delims=" %%F in ('dir /b /s "c:\myFileToSearchFor.ext"') do set "pathToMyFile=%%~dpF"
This batch script will set a variable to the first found location:
for /f "delims=" %%F in ('dir /b /s "c:\myFileToSearchFor.ext"') do (
set "pathToMyFile=%%~dpF"
goto :foundIt
)
:foundIt
There is no function/program that I know of that performs this. If you need efficiency you could write a program that does a fancy tree search through all the directories. I did however find a solution in batch!
#echo off
for /r "C:\somebasepath" %%i in (*) do (
if "%%~nxi" EQU "%1" (
echo %%i
break
)
)
Passing the file to be found as the first argument to the batch file. But this is very very slow if its in a deep directory.