Recursive search by file list - batch-file

I have a TXT file with a list of names like:
Test
Word
etc.
I need to search ( recursive, so also in subfolder ) if one of that name match with a file. This is my attempt:
#echo off
Set MyPath=C:\Folder
for /f %%i in (list.txt) do (
echo File with word %%i: >> result.txt
echo. >> result.txt
findstr /M /C:%%i /S "%MyPath%\*.*" >> result.txt
echo. >> result.txt
)
The result.txt i want is:
File with word test:
C:\Folder\test.exe
C:\Folder\my test.txt
C:\Folder\another test.doc
C:\Folder\tatest.bat
File with word Word:
C:\Folder\This is my word.exe
C:\Folder\CoolWord.txt
C:\Folder\hello word.bat
So how to improve that batch and make it recursive also for the subfolder of the initial dir?
Thanks

Test this: It will write result.txt with the results for each word.
#echo off
(
for /f "usebackq delims=" %%a in ("list.txt") do (
echo "File with word %%a:"
echo.
set "flag="
for /r "c:\folder" %%b in ("*%%a*") do (echo %%b&set flag=1)
if not defined flag echo No Matches
echo.
)
)>"result.txt"

dir /s /b C:\Folder\*.* >allfiles.txt
for /f %%i in (list.txt) do (
echo File with word %%i: >> result.txt
echo. >> result.txt
findstr /M /C:%%i /S "allfiles.txt" >> result.txt
echo. >> result.txt
)

#echo off
Set MyPath=C:\Folder
(for /f "delims=" %%i in (list.txt) do (
echo File with word %%i:
echo/
dir /B /S "%MyPath%\*%%i*"
echo/
)) > result.txt

Related

How to delete only text files except few files

In a certain path I have some different kinds of file type. Eg., .txt, .bas, .cls, etc.
I need to delete only the text files in that path except few files.
For eg, if the path has a.txt, b.txt, c.txt, aa.bas, bb.cls, it should delete only a.txt. It should not delete b.txt and c.txt (Also it should not delete the other extension files).
To delete all ?.txt files in the root folder, excluding b.txt and c.txt
#echo off
for %%i in (?.txt) do (
if not "%%~nxi"=="c.txt" if not "%%~nxi"=="b.txt" echo del "%%i"
)
To do this in the root and subdirectories:
#echo off
for /R %%i in (?.txt) do (
if not "%%~nxi"=="c.txt" if not "%%~nxi"=="b.txt" echo del "%%i"
)
If the files are to be all *.txt files and not just single digit as per your example (add /R to recurse:
#echo off
for %%i in (*.txt) do (
if not "%%~nxi"=="c.txt" if not "%%~nxi"=="b.txt" echo del "%%i"
)
Similarly, but using findstr to only exclude:
#echo off
for /f %%i in ('dir /b /a-d ^|findstr /vi "b.txt" ^|findstr /vi "c.txt"') do (
echo del "%%i"
)
and to search only include:
#echo off
for /f %%i in ('dir /b /a-d ^|findstr /i "a.txt"') do (
echo del "%%i"
)
and to include and search subdirectories:
#echo off
for /f %%i in ('dir /b /s /a-d ^|findstr /i "a.txt"') do (
echo del "%%i"
)
On all of the above examples, remove echo to actually perform the delete, echo is used as a safety measure and will only display the del result to console.
Edit
Seeing as you specifically have a list of files (as per one of you comments) to exclude, you can use something like this. You have to create a file called exclusion.txt and add the files to exclude in list form:
b.txt
c.txt
file with space.txt
d.txt
Then create the batch file and add the code below. When ran, it will prompt for the file extention to filter on, where you can type an extension. i.e txt or simply press enter to perform a delete on all files, except the excluded ones. Just to be safe, I added an additional for loop to simply echo the files and prompt you if you are sure you want to delete the files.
#echo off
set cnt=0 & set excl= & set ext=
echo(
if not exist exclusion.txt echo You have not created an "exclusion.txt" file. & echo( & echo You need to create it first, then rerun the script & echo( & pause & goto :eof
echo Ensure you have listed all files to be excluded in "exclusion.txt" file
echo(
set /p "ext=Add File extention to search on (txt, pdf, etc), or press enter for all files: "
if not defined ext goto cont
if not "%ext:~0,1%"=="." set "ext=.%ext%"
set "ext=*%ext%"
:cont
setlocal enabledelayedexpansion
for /f "delims=" %%a in (exclusion.txt) do (
set /a cnt+=1
set "nlr!cnt!=%%a"
)
for /l %%i in (1,1,%cnt%) do (
if not defined excl (
set "excl=!nlr%%i!"
) else (
set "excl=!excl! !nlr%%i!"
)
)
echo(
echo WARNING: You are about to delete the following files!!
echo(
for /f "delims=" %%i in ('dir /b /a-d %ext% ^|findstr /VIE "%excl%"') do (
if /i not "%%i"=="exclusion.txt" if not "%%i"=="%~0" echo %%i
)
echo(
Choice /c YN /m "Are you sure you want to delete these files?"
if %errorlevel% equ 2 goto :eof
for /f "delims=" %%i in ('dir /b /a-d %ext% ^|findstr /VIE "%excl%"') do (
if /i not "%%i"=="exclusion.txt" if not "%%i"=="%~0" del %%i
)

How do I combine files in order

I have/found a windows batch script that will combine csv files from all sub-directories. It works great in Windows 10 but when I run the script in Windows 7, all the files are out of order. How do I force the order in which to combine the csv files?
echo #off
for /r %%i in (*.csv) do (
if not %%~nxi == output.csv (
echo %%~nxi >> output.csv
echo %%i
echo %%~nxi
type "%%i" >> output.csv
echo. >> output.csv
echo. >> output.csv
)
)
Just a little change to your code will do the job:
#echo off
FOR /F "usebackq delims=" %%i IN (`dir /s /b /O:N *.csv`) do (
if not "%%~nxi" == "output.csv" (
echo %%~nxi >> output.csv
echo %%i
echo %%~nxi
type "%%i" >> output.csv
echo. >> output.csv
echo. >> output.csv
)
)
Point is to use another command's out -- use dir to control the sorting order.
/b for clean output by dir
/O for ordering, N -- name.
check FOR /? and dir /? for more details.
PS: you may wanna use:
echo %%~dpnxi >> output.csv
instead of line 4's echo %%~nxi >> output.csv , to show full path of each file in your output.csv.
This is just a slight modification to POW's answer that should give you better performance. This technique keeps the file open for writing. When you use the append multiple times, it is opening and closing the output file. So the file pointer has to be reset every time it outputs to the file.
#echo off
(FOR /F "usebackq delims=" %%i IN (`dir /s /b /O:N *.csv`) do (
echo %%~nxi
echo %%i >con
type "%%i"
echo.
echo.
)
)>output.tmp
rename output.tmp output.csv
Here is another possible solution:
#echo off
for /R %%A IN (*.csv) do (
if not "%%~nxA"=="output.csv" (
(echo %%~fA && type "%%~fA" && echo. && echo.)>>output.csv
echo Processed: %%A
echo %%~nxA
)
)
with much less code.
Using /R option with for to loop through subfolders in %cd%.
We want to parse ALL csv files so, we specify it in parenthesis with (*.csv).
Then, we check if csv file currently processed is output.csv.
If not, then we append full path of the csv ("%%~fA") file, its content (type "...") and two newlines (echo.) to output.csv. This condition is not really required, but added to be on-topic with the question. Also, if you don't want to append full path to output.csv, but filename and extension only just replace %%~fA with %%~nxA.
After that, we echo current file processed and its filename and extension.
If file currently processed is output.csv, then we repeat the loop.
Now, output.csv has the contents of all csv files in all subdirectories.
So, now open a new cmd and type the following commands. Read the output carefully:
for /?
if /?
echo /?
type /?
Some suggestions for further reading:
https://ss64.com/nt/for_cmd.html
https://ss64.com/nt/for_r.html
https://ss64.com/nt/syntax-redirection.html
What does "&&" in this batch file?
Thanks to all of you for your help. After reading all the responses, I realized that I could get around the windows sorting problem by sorting into a second file and then reading it from there.
dir /b /s /O:N *.csv | sort > file.txt
for /f %%A IN (file.txt) do (
if not %%~nxA == output.csv (
echo %%~dpnxA
echo %%~nxA >> output.csv
type %%A >> output.csv
echo. >> output.csv
echo. >> output.csv
)
)
Again, thank you for all your help.

Exclude certain file extensions from random file selection - batch script

I'm in the process of making a script that selects 25 random tracks from a user specified folder and adds them into an .m3u playlist. The trouble I have is that my music folders include various other files as well (eg: .txt, .jpg, .png, .nfo, etc...)
So I'm looking for a way of excluding the extensions listed above, limiting the script to just work with audio files. Any help would be much appreciated!
Here is the code so far... It has been stitched together from various sources so accept my apologies if it is a little crude:
#echo off
title Multiple Choice Menu
:home
cls
echo.
echo Select a genre:
echo =============
echo.
echo 1) Jungle
echo 2) D'n'B
echo 3) Reggae
echo 4) Hip-Hop
echo 5) Exit
echo.
set /p genre=Type option:
if "%genre%"=="1" cd /D "D:\NL Safe 2.0\High Quality\Jungle"
if "%genre%"=="2" cd /D "D:\NL Safe 2.0\High Quality\DnB\Standard DnB"
if "%genre%"=="3" cd /D "D:\NL Safe 2.0\High Quality\Reggae
if "%genre%"=="4" cd /D "D:\NL Safe 2.0\High Quality\Hip-Hop"
if "%genre%"=="5" exit
:: Clear existing Playlist
#echo. > C:\Users\Brew\Desktop\random.m3u
:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
dir /b /s /a-d %1 | findstr /n "^" >"%tempFile%"
:: Count the files
for /f %%N in ('type "%tempFile%" ^| find /c /v ""') do set cnt=%%N
:: Open 25 random files
for /l %%N in (1 1 25) do call :openRandomFile
:: Delete the temp file
del "%tempFile%"
:openRandomFile
set /a "randomNum=(%random% %% cnt) + 1"
for /f "tokens=1* delims=:" %%A in (
'findstr "^%randomNum%:" "%tempFile%"'
) do (
setlocal EnableDelayedExpansion
set tune=%%B
#echo !tune! >> C:\Users\Brew\Desktop\random.m3u
)
Assuming your song's folder is on %1.
The dir command supports wildcards in the idea that
dir *.txt *.xml
will only list .txt and .xml files.
So you can try doing this instead:
...
:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
pushd %1
dir /b /s /a-d *.mp3 *.EXT1 *.EXT2 | findstr /n "^" >"%tempFile%"
popd
...
Where EXT will be the extensions you want to match.
This will create your %tempFile% with only the files you want. Since the code that selects a file ramdomly works, as I see, over this file, it won't need to change at all.
I couldn't get dir to work with both target directory and wildcards.
Hope it helps.
This is why i used pushd and popd.
Thanks Daniel,
I had another go at it an finally got something working on my own. I used a series of If statements to put the random file through an extension validation check
This is the working script
#echo off
title Multiple Choice Menu
:home
cls
echo.
echo Select a task:
echo =============
echo.
echo 1) Jungle
echo 2) D'n'B
echo 3) Reggae
echo 4) Hip-Hop
echo 5) Exit
echo.
set /p genre=Type option:
if "%genre%"=="1" cd /D "D:\NL Safe 2.0\High Quality\Jungle"
if "%genre%"=="2" cd /D "D:\NL Safe 2.0\High Quality\DnB\Standard DnB"
if "%genre%"=="3" cd /D "D:\NL Safe 2.0\High Quality\Reggae
if "%genre%"=="4" cd /D "D:\NL Safe 2.0\High Quality\Hip-Hop"
if "%genre%"=="5" exit
:: Clear existing Playlist
#echo. > C:\Users\Brew\Desktop\random.m3u
:: Create numbered list of files in a temporary file
set "tempFile=%temp%\%~nx0_fileList_%time::=.%.txt"
dir /b /s /a-d %1 | findstr /n "^" >"%tempFile%"
:: Count the files
for /f %%N in ('type "%tempFile%" ^| find /c /v ""') do set cnt=%%N
:openRandomFile
echo opening random file.....
set /a "randomNum=(%random% %% cnt) + 1"
for /f "tokens=1* delims=:" %%A in (
'findstr "^%randomNum%:" "%tempFile%"'
) do (
setlocal EnableDelayedExpansion
set tune=%%B
FOR %%i IN ("!tune!") do call :CheckifMusic
)
:CheckifMusic
echo checking now
FOR %%i IN ("!tune!") DO (
SET fileextension=%%~xi
IF !fileextension!==.aif goto ResultTrue
IF !fileextension!==.flac goto ResultTrue
IF !fileextension!==.m4a goto ResultTrue
IF !fileextension!==.mp3 goto ResultTrue
IF !fileextension!==.wav goto ResultTrue
IF !fileextension!==.wma goto ResultTrue
echo fail
echo !fileextension!
goto openRandomFile
:ResultTrue
echo pass
echo !fileextension!
#echo !tune! >> C:\Users\Brew\Desktop\random.m3u
set /A COUNTER=COUNTER+1
IF !COUNTER!==25 (
echo finished
pause
goto Done
) ELSE (
goto openRandomFile
)
:Done
echo.
:: Delete the temp file
del "%tempFile%"
exit
)
pause
Probably not the cleanest way to do it, but hey - It works!
replace
dir /b /s /a-d %1 | findstr /n "^" >"%tempFile%"
with
dir /b /s /a-d %1 | findstr /n /L /E /I /c:".mp3" /c:".wav">"%tempFile%"
Where the /c:".mp3"... can be extended as many times as you desire to select your target filetypes.
or
with
dir /b /s /a-d %1 | findstr /n /V /L /E /I /c:".jpg" /c:".txt">"%tempFile%"
Again repeating the /c:".jpg"... as many times as you desire to select your target exclude-me filetypes.
The /i means "case-insensitive", /e means "at the end of the line" /L means "literal match, not regex" and /v means "output non-matching"

Replace text in .bat file

I have 2 folders in folder called C:\durvi\mmi_test\mmidurvi which are
C:\durvi\mmi_test\mmidurvi\durvyauu
C:\durvi\mmi_test\mmidurvi\sgdf
Both these folders have Connections.xml file
I would like to replace any occurance of ql99015 with dd32261
A sample format of file is as below
<pre><anyType xsi:type="xsd:string">ql99015</anyType>
<anyType xsi:type="xsd:string">ql99015_flowreeng_Anthony</anyType> </pre>
I tried something like below but does not work:
for /D %%f in (c:\durvi\mmi_test\mmidurvi\*) do (
cd %%f
if not exist "Connections.xml" (echo this file does not exist)&goto :eof
SETLOCAL=ENABLEDELAYEDEXPANSION
ren "Connections.xml" "Connections1.xml"
for /f %%a in (Connections1.xml) do (
set write=%%a
echo %%a
if !write!=="ql99015" set write="dd32261"
echo !write! >> Connections.xml
)
del "Connections1.xml"
cd..
)
Thanks for your help in advance!
Change the script to:
SETLOCAL ENABLEDELAYEDEXPANSION
for /r %%a in (connections.xml) do (
move "%%a" "%%a.temp"
for /f "usebackq tokens=*" %%b in ("%%a.temp") do (
set write=%%b
echo !write:ql99015=dd32261! >> "%%a"
)
del "%%a.temp"
)

Batch: Copy a list (txt) of files ignoring extension

I have the next batch file, but its matching by file name. This time the list I have is huge and has file names without extension, but can I ignore the extension and copy for example: filename.* to the destination folder?
This is the current script:
title Deploying Edithor
set src_folder=S:\ApliTelinver\Compilacion\Edithor 10.5\Pipe
set dst_folder=J:\alazarev\Objetos-Migracion-Pipe
set filelist=filelist-pipe.txt
echo Origen: %src_folder% >> "pipemigracion-!datetimef!.log"
echo Destino: %dst_folder% >> "pipemigracion-!datetimef!.log"
echo.
REM for /f %%i in (%filelist%) DO xcopy /S/E/U/Y "%src_folder%\%%i" "%dst_folder%" > "%dd%.log"
for /f "delims=" %%i in (%filelist%) do (
xcopy /S/E/U/Y "%src_folder%\%%i" "%dst_folder%" >> "pipemigracion-!datetimef!.log"
)
echo Success. >> "pipemigracion-!datetimef!.log"
echo.
echo Done - Check log pipemigracion-!datetimef!.log
echo.
pause
goto start
Here's how I've understood the question. The file list, filelist-pipe.txt, contains file names, and all of the names are without extensions.
If so, you only need to append .* to the source file path in the XCOPY command:
title Deploying Edithor
set src_folder=S:\ApliTelinver\Compilacion\Edithor 10.5\Pipe
set dst_folder=J:\alazarev\Objetos-Migracion-Pipe
set filelist=filelist-pipe.txt
echo Origen: %src_folder% >> "pipemigracion-!datetimef!.log"
echo Destino: %dst_folder% >> "pipemigracion-!datetimef!.log"
echo.
REM for /f %%i in (%filelist%) DO xcopy /S/E/U/Y "%src_folder%\%%i" "%dst_folder%" > "%dd%.log"
for /f "delims=" %%i in (%filelist%) do (
xcopy /S/E/U/Y "%src_folder%\%%i.*" "%dst_folder%" >> "pipemigracion-!datetimef!.log"
)
echo Success. >> "pipemigracion-!datetimef!.log"
echo.
echo Done - Check log pipemigracion-!datetimef!.log
echo.
pause
goto start
Please let me know if I'm still missing something.

Resources