i'm working in cmd and i need a little help. I want to modify this code (which is working) :
#echo off
for /f %%a in ('findstr /s /m %3 "%1*.%2"') do (
findstr /S /R /N "^" "%%a" | find /C ":"
)
So, this code has 3 parameters (1.path, 2.extension and 3. string) and only searches for files that contain that string. The search is conducted in the directory sent as parameter and all the subfolders. This code will show how many lines each file has only if the file contains the string sent as parameter.
Now i want to modify this code in a way that i can send 4th parameter which is a number, and i want it to (obviously echo YES!) only if the number of lines in file is greater than the number sent as parameter. However, my code down below isn't working (i have tried many solutions which includes ( [ " ' etc. ) but i can't get it to work.
#echo off
for /f %%a in ('findstr /s /m %3 "%1*.%2"') do (
if findstr /S /R /N "^" "%%a" | find /C ":" gtr %4 echo YES!
)
Can you help me? :)
Here you go, made to look a little different.
This includes filters to prevent the Dir command from reading directories, system files and reparse points too:
#ECHO OFF
FOR /F "DELIMS=" %%A IN ('DIR /B /S /A:-D-S-L "%~1*.%2"') DO (
FOR /F "TOKENS=3 DELIMS=:" %%B IN ('FIND /I /C "%~3" "%%A"') DO (
IF %%B GTR %4 (
ECHO File %%A has more than %4 lines matching the string %3, it has%%B.
)
)
)
This uses FindStr as in your example, but it's a little slower:
#ECHO OFF
FOR /F "DELIMS=" %%A IN ('FINDSTR /S /M /I /C:"%~3" "%~1*.%2"') DO (
FOR /F "TOKENS=3 DELIMS=:" %%B IN ('FIND /I /C "%~3" "%%A"') DO (
IF %%B GTR %4 (
ECHO File %%A has more than %4 lines matching the string %3, it has%%B.
)
)
)
(Remember that the script was designed to accept specific format and order of input parameters).
Related
I could use some help, I've tried similar topics but I couldn't find exactly what I was looking for.
What I need is a batch script which loops through a directory searching for files of type .pro but don't begin with the character {.
The script then searches all the files and echoes the lines which are found between the numbers 574, and 575,.
I've got all the things done except when I try to check for file names I cant get it to work properly and it seems so simple.
My script looks like this:
#echo off
set "sPath=C:\Users\jspajic\Desktop\batskripte\test\test files"
set "ispis=C:\Users\jspajic\Desktop\batskripte\test\Opera_procesi_DataTabovi.txt"
echo %sPath% > %ispis%
pushd %sPath%
for %%f in (*.pro) do ( :: ---> I guess this part needs to be altered
setlocal enabledelayedexpansion
for /f "delims=]" %%a in ('findstr /n /B "574," "%%f"') do (set s=%%a )
if !s! neq 0 (
for /f "delims=]" %%b in ('findstr /n /B "575," "%%f"') do (set kraj=%%b)
if !kraj! neq 0 (
#set /a "ss=s+1"
#set /a "kraj=kraj+0"
#set /a "s=s+0"
if !ss! NEQ !kraj! (
#echo:
echo %%f
#set /a "counter=1"
for /F "tokens=1* delims=:" %%A in ('type "%%f" ^| findstr /n "^"') do (
if !counter! GTR !s! if !counter! LSS !kraj! echo.%%B
#set /a "counter=counter+1"
)
)
)
)
endlocal
) >> %ispis%
popd
I tried with for /f "delims=" %%a in ('dir /B *.pro^|findstr "[A-z]*\.pro" ')
or with similar ideas but I cant get it to work cause I just dont know batch scripts that well.
for %%f in (*.pro) do ( set "dummy=%%f"
setlocal enabledelayedexpansion
if "!dummy:~0,1!" neq "{" (
should solve your problem. Note that it adds an extra level of parentheses, so a matching ) needs to be added after the endlocal but you seem to be adept at doing that.
Assign the filename to a dummy variable, then see whether the 1st character of that dummy is NOT equal to "{" before executing the rest of the code.
From the prompt, set /? will show documentation about substringing - you seem to have delayed expansion worked out.
Because your character does not have a case, (upper | lower), and your search directory is already current; this can be easily catered for using EOL in your For loop:
For /F "EOL={Delims=" %%f In ('Dir/B/A-D *.pro') Do (
use for /f with dir, filtered by findstr (eliminate every token that starts with {):
for /f "delims=" %%f in ('dir /b /a-d *.pro^|findstr /vb "{"') do (
I want to find two different strings in .txt file. I need two scripts, first script to find last row that contains these strings together and second script to find last row that contains these strings seperately. I tried to write somethings but I go off the project.
This what i have tried so far as code :
#echo off
for /f %%i in ('find /v /c "" ^< deneme.txt') do set /a lines=%%i
echo %lines%
set /a startLine=%lines% - 1
more /e +%startLine% deneme.txt > temp.txt
find "ali" temp.txt|find "veli"
del temp.txt
Thanks for help.
#echo off
set "string1=ali"
set "string2=veli"
set "file=deneme.txt"
for /f "delims=" %%a in ('findstr /i "\<%string1%\>" %file% ^|findstr /i /v "\<%string2%\>" ') do set "out1=%%a"
for /f "delims=" %%a in ('findstr /i "\<%string2%\>" %file% ^|findstr /i /v "\<%string1%\>" ') do set "out2=%%a"
for /f "delims=" %%a in ('findstr /i "\<%string1%\>" %file% ^|findstr /i "\<%string2%\>" ') do set "out3=%%a"
echo last line with %string1%: "%out1%"
echo last line with %string2%: "%out2%"
echo last line with both: "%out3%"
for explanations, see for /? and findstr /?
I have a folder full of text files that I need to split based on the (optional) presence of a delimiter. I found an answer for how to actually split the file here: Split text file into 2 files by separator
#echo off&setlocal
set "file=_frmCore.frm"
for /f "delims=[]" %%i in ('^<"%file%" find /n "SearchTermHere"') do set "split=%%i"
(for /f "tokens=1*delims=[]" %%i in ('^<"%file%" find /n /v ""') do if %%i lss %split% echo(%%j)>"%file%.new1"
<"%file%">"%file%.new2" more +%split%
type "%file%.new?"
Works great for what it is, but I need a few refinements and not sure where to start. Looking for:
Wrap it in a loop for all files in the directory (no subfolders to worry about)
"SearchTermHere" is the first on a line (the only on a line), with a specific term on the previous line that I'd rather match for safety... how can I tell it "PreviousLine/r/nSearchTermHere/r/n"? Unsure of the correct syntax here.
Rather than creating two new files, move the "after search term" portion to a new file and remove it from the original
Parameterize folder name to operate in so I can call from other programs
(apologies... I've tried deciphering this code and finding out what does what and trying to go from there, but this stuff is not my cup of tea and a strong push in the right direction would be wonderful)
#ECHO OFF >NUL
SETLOCAL enableextensions
rem enabledelayedexpansion
set "_files=*.frm"
set "_sfind=SearchTermHere"
if not "%~1"=="" if exist "%~1\" (
pushd "%~1"
set "_popd=popd"
) else ( set "_popd=" )
for /F "delims=" %%G in ('findstr /m "^%_sfind%$" %_files%') do (
type NUL > "%%G.new1"
type NUL > "%%G.new2"
for /f "delims=:" %%i in ('findstr /n "^%_sfind%$" "%%G"') do (
for /f "tokens=1* delims=:" %%I in ('findstr /n "^" "%%G"') do (
if %%I lss %%i (
>> "%%G.new1" echo(%%J
)
if %%I gtr %%i (
>> "%%G.new2" echo(%%J
)
)
)
rem remove `ECHO` from next line no sooner than debugged!
ECHO move /Y "%%G.new1" "%%G"
type "%%G.new?"
)
%_popd%
Changes made in your code:
Wrap it in a loop for all files in the directory: see for /F "delims=" %%G loop against all files matching your criteria: findstr /m "^%_sfind%$" %_files%.
"SearchTermHere" is the first on a line (the only on a line): ^=beginning of line and $=end of line in findstr /m "^%_sfind%$" %_files%; used findstr command rather than find.
Rather than creating two new files, move the "after search term" portion to a new file and remove it from the original: see the move /Y "%%G.new1" "%%G" workaround. Operational move command is ECHOed here merely for debugging purposes. Remove ECHO from that line no sooner than debugged!
Parameterize folder name to operate in so I can call from other programs:
call "batch path\31749577.bat" "folder path"
see %~1 test: if a parameter is supplied to the batch and represents a folder, (more in Command Line arguments (Parameters)) and
see pushd - popd pair: PUSHD changes the current directory/folder and store the previous folder/path for use by the POPD command.
The tricky <"%%G">"%%G.new2" more +%%i command substituted with less effective but clear to understand if %%I gtr %%i ( ... inside the %%I loop. However, next code snippet (entire %%G loop) will work as well:
for /F "delims=" %%G in ('findstr /m "^%_sfind%$" %_files%') do (
for /f "delims=:" %%i in ('findstr /n "^%_sfind%$" "%%G"') do (
>"%%G.new1" (for /f "tokens=1* delims=:" %%I in ('
findstr /n "^" "%%G"') do if %%I lss %%i echo(%%J)
<"%%G">"%%G.new2" more +%%i
)
rem remove `ECHO` from next line no sooner than debugged!
ECHO move /Y "%%G.new1" "%%G"
type "%%G.new?"
)
Excuse me. Although your description is extensive, it is also confusing. The Batch file below:
Search for a line that is "SearchTermHere".
If the previous line is "PreviousLine":
Move from line after SearchTerm up to end of file to another file
Repeat previous process on all files in folder.
.
#echo off
setlocal EnableDelayedExpansion
set "find=SearchTermHere"
set "prevLine=PreviousLine"
rem Process the folder given in parameter
cd %1
rem Process all files in folder
for /F "delims=" %%F in ('dir /A-D /B') do (
rem Get the line number of the search line - 1
set "numLines="
for /F "delims=:" %%a in ('findstr /N "^%find%$" "%%F"') do set /A "numLines=%%a-1"
if defined numLines (
rem Open a code block to read-input-file/create-output-file
< "%%F" (
rem Copy numLines-1 lines
for /L %%i in (1,1,%numLines%) do (
set "line="
set /P "line="
echo(!line!
)
rem If the line before search is prevLine
if "!line!" equ "%prevLine%" (
rem Copy just the search line to original file
set /P "line="
echo !line!
rem and copy the rest of lines to another file
findstr "^" > "%%~nF-PART2%%~xF"
)
) > "%%F.tmp"
if exist "%%~nF-PART2%%~xF" (
rem Replace original file with created output file (first part)
move /Y "%%F.tmp" "%%F" > NUL
) else (
rem Remove the output file
del "%%F.tmp"
)
)
)
For a further explanation of this method, see this post.
Sorry, I was unable to use either of the proposed solutions. However they did help - I spent the last two days learning about the (odd) syntaxes and operations involved in batch files and came up with the following. It doesn't do quite everything that I was looking for (and I altered the program that outputs the files a bit for further support), but it does get the job done:
#ECHO off
setlocal EnableDelayedExpansion
:: change the working directory to match the input
cd /D %~d1
cd %~p1\
:: loop all .frm files and find the CodeBehindForm string
for %%F in (*.frm) do (
for /F "delims=[]" %%a in ('^<%%F find /n "CodeBehindForm"') do (
if %%a gtr 0 (
for /F "tokens=1*delims=[]" %%i in ('^<"%%F" find /n /v ""') do if %%i gtr %%a echo(%%j)>>"%%~nF.vb"
for /F "tokens=1*delims=[]" %%i in ('^<"%%F" find /n /v ""') do if %%i lss %%a echo(%%j)>>"%%~nF.fwm"
:: if the codebehind was found and parsed out, there's a .fwm and .vb file
:: remove the original
if exist %%~nF.vb del %%F
)
)
:: change the .fwm extensions back to their original .frm extensions
ren *.fwm *.frm
I'm sure it's not "correct" in many ways, but for now it gets the job done.
Thanks for the help.
This is a very specific question, so I've separated it into 3 parts.
Look in all subfolders for a certain file: world.sav, but only 1 level down, i.e.
C:\workingdir\foo\world.sav
C:\workingdir\bar\world.sav
C:\workingdir\baz\world.sav
C:\workingdir\qux\world.sav
is fine, but
C:\workingdir\foo\bar\world.sav
C:\workingdir\world.sav
isn't, etc.
Sort these world.sav files by date modified (newest first).
Display the name of the subfolder each world.sav file is in, in the previously sorted order. i.e. if the above list was date-sorted into
C:\workingdir\qux\world.sav (newest)
C:\workingdir\bar\world.sav
C:\workingdir\foo\world.sav
C:\workingdir\baz\world.sav (oldest)
then the output would be
qux
bar
foo
baz
I've tried numerous methods involving DIR, FORFILES and manipulation of variables, but the 2 main problems I've come across so far are
Both commands mentioned above will arrange by subfolder, then by date, and I can't find a way to avoid it.
Date formatting. It appears to be different for every localization of Windows, and I really want this to be locale-independent.
Also, it must support spaces in folder names.
EDITED version with a wait message:
#echo off
echo Please wait...
cd /d "c:\workingdir"
(for /d %%a in (*) do #robocopy "%%a" "%%a" world.sav /L /nocopy /is /njh /njs /ndl /nc /ns /ts)|(
#cls
for /f "tokens=2*" %%b in ('sort /r') do #for %%z in ("%%~dpc\.") do #echo %%~nz
)
cd /d "%~dp0"
echo.
pause
original version below
This works here:
robocopy is used on each folder in the directory to generate a list (UTCdate time drv:\path\world.sav format) and that is sorted to get most recent at the top of the list, which the second for parses to extract the drv:\path\folder\world.sav and the last for loop prints out just the folder name.
#echo off
cd /d "c:\workingdir"
(for /d %%a in (*) do #robocopy "%%a" "%%a" world.sav /L /nocopy /is /njh /njs /ndl /nc /ns /ts)|for /f "tokens=2*" %%b in ('sort /r') do #for %%z in ("%%~dpc\.") do #echo %%~nz
pause
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET /a count=0
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*" '
) DO IF exist "%sourcedir%\%%a\world.sav" CALL :set$ "%%a"
IF %count%==0 ECHO No files found&GOTO :EOF
IF %count%==1 ECHO %$1%&GOTO :EOF
:sortol
SET /a start=1
SET /a swap=0
:sortil
CALL :compdt
IF %start% neq %count% GOTO sortil
IF %swap% neq 0 GOTO sortol
FOR /l %%a IN (1,1,%count%) DO CALL ECHO %%$%%a%%
GOTO :EOF
:set$
SET /a count+=1
SET "$%count%=%~1"
GOTO :eof
:compdt
CALL SET f1=%%$%start%%%
SET /a START +=1
CALL SET f2=%%$%start%%%
FOR /f %%a IN (
'echo f^|xcopy /L /y /d "%sourcedir%\%f1%\world.sav" "%sourcedir%\%f2%\world.sav"'
) DO SET copies=%%a
IF %copies%==0 GOTO :EOF
SET /a swap +=1
SET /a START -=1
SET "$%start%=%f2%"
SET /a START +=1
SET "$%start%=%f1%"
GOTO :eof
This worked for me. You'd need to set sourcedir to suit your purpose.
Essentially, it builds a list of the next-level-down directory names which contain the target filename in variables $1...$whatever, then sorts the names using a simple bubble-sort which relies on the characteristics of xcopy. XCOPY's /L switch simply lists the files that would be copied; /y tells it to 'go ahead (and not copy)' and /d says 'only later files.ECHOingftellsxcopythat the desired "copy" is a file-copy, so it responds1 file(s) copiedor0...` as its last line, depending on whether the source file was later than the destination.
To reverse the order, simply change the if %copies%==0 to if %copies%==1
An idea :
#echo off
Setlocal EnableDelayedExpansion
set $WorkDir="C:\eh\guh\blugh\fneh\mork\workingdir"
for /f "tokens=*" %%a in ('dir /s/b/a-d %$WorkDir%') do (
for /f "tokens=9 delims=\" %%b in ('echo %%a') do (
if /i "%%b"=="world.sav" call:next "%%~pa" %%~ta
)
)
::Resultat
for /f "tokens=2 delims==" %%r in ('set #') do echo %%r
exit/b
:next
for /f "tokens=7 delims=\" %%c in ('echo %~1') do set $Path=%%c
for /f "tokens=1-3 delims=/" %%c in ('echo %~2') do set #%%e%%d%%c=!$path!
I work with hundreds of thousands of folders/files, most of which have certain log files. It takes a lot of time to manually navigate through the folders to grab the logs, so Ive been using a script to do it.
Its a 2 parter. First part runs overnight to parse all of the directories (they change daily and new logs are added very often, so I index everything nightly to keep the index current).
This first part is automatic and I never touch it, it just runs nightly. Output goes to a txt file, which is used when I execute the second script.
Second script is where I put in keywords of what log I am looking for. This script relies on the txt output from the first script to quickly locate the file and pull it down.
(The reason I do it this way is because its a 5 second task to parse 300,000 line text file looking for a file, and its a 15-30 minute job to search (index all of the network shares). This way I can get my logs in 5 seconds and not 30+ minutes).
Prior to last week the log directories consisted of about 5000 files and folders. This past weekend IT switched over to a new system, and it is now consisting of over 500,000 files and folders. They dumped archives, and a bunch of other files in there that I do not need.
First script used to index it in about 10-15 minutes (its a network share, actually 4 network shares), no problem overnight. While now this is a 4+ hour feat. I need to be able to exclude certain directories during indexing thereby reducing the 500,000 file/folder count back down to under 5,000.
Ive been using this command to index:
dir /b /-d /-p /s /A:-D > C:\output.txt
I need have the indexing skip any directory containing the words "Common" or "Old" in them, and potentially others as well. The goal is to save time by not going inside of these directories at all.
I tried looking into PowerShell to do this, but I know nothing about it.
I need the output to be in the following format:
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\dbInstaller.exe
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\DisplayDriver.nvi
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\DisplayDriverExt.dll
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\license.txt
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\mcu.ex_
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvae.inf
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvak.inf
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvapi.dl_
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvapi64.dl_
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvcompiler.dl_
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvcompiler32.dl_
C:\NVIDIA\DisplayDriver\GeForce332.21Driver\Display.Driver\nvcplsetupeng.exe
Thanks!
#ECHO OFF
SETLOCAL
SET "sourcedir=."
(
FOR /f "delims=" %%a IN (
'dir /b /s /ad "%sourcedir%\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO ( FOR /f "delims=" %%b IN ('dir /b /a-d "%%a" 2^>nul') DO ECHO(%%a\%%b
)
)>newfile.txt
GOTO :EOF
I used a file named q22903564.txt containing exclusion words for my testing.
Produces newfile.txt.
Naturally, choice of sourcedir, q22903564.txt and newfile.txt are all in your court...
#ECHO OFF
SETLOCAL
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
SET "sourcedir=."
:: get a dir listing from the root
(
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO (ECHO("%%~fa")
)>"%tempfile%b"
:again
(
FOR /f "usebackqdelims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /ad "%%~a\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO FOR /f "delims=" %%c IN ('ECHO("%%~a\%%b"^|findstr /x /v /i /l /g:"%tempfile%b"') DO ECHO "%%~c"
)
)>"%tempfile%c"
FOR %%a IN ("%tempfile%c") DO SET /a sizec=%%~za
IF %sizec% gtr 0 TYPE "%tempfile%c">>"%tempfile%b"&GOTO again
(
FOR /f "usebackqdelims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /a-d "%%~a\*" 2^>nul'
) DO ECHO(%%~a\%%b
)
)>newfile.txt
DEL "%tempfile%*"
GOTO :eof
Well - need to charge you extra for doing what, according to some, is impossible.
#ECHO OFF
SETLOCAL
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
SET "sourcedir=."
:: get a dir listing from the root
(
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO (ECHO("%%~fa")
)>"%tempfile%b"
SET /a sizec=0
:again
SET "skipcnt=usebackq"
IF %sizec% gtr 0 (
FOR /f %%a IN ('type "%tempfile%b" ^|find /c /v ""') DO SET "skipcnt=usebackqskip=%%a"
TYPE "%tempfile%c">>"%tempfile%b"
)
(
FOR /f "%skipcnt%delims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /ad "%%~a\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO FOR /f "delims=" %%c IN ('ECHO("%%~a\%%b"^|findstr /x /v /i /l /g:"%tempfile%b"') DO ECHO "%%~c"
)
)>"%tempfile%c"
FOR %%a IN ("%tempfile%c") DO SET /a sizec=%%~za
IF %sizec% gtr 0 GOTO again
(
FOR /f "usebackqdelims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /a-d "%%~a\*" 2^>nul'
) DO ECHO(%%~a\%%b
)
)>newfile.txt
DEL "%tempfile%*"
GOTO :eof
Third time's a charm. This version works out how many lines of directory it's already processed and skips those lines when re-processing the concatenated lists b and c. IOW, it only processes the additions.
And in typing this, I've realised there's another little simplification... have to wait for morning tea, though...
#ECHO OFF
SETLOCAL
:: make a tempfile
:maketemp
SET "tempfile=%temp%\%random%"
IF EXIST "%tempfile%*" (GOTO maketemp) ELSE (ECHO.>"%tempfile%a")
SET "sourcedir=."
:: get a dir listing from the root
(
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO ECHO(%%~fa
)>"%tempfile%c"
SET /a sizec=0
:again
SET "skipcnt=usebackq"
IF %sizec% neq 0 FOR /f %%a IN ('type "%tempfile%b" ^|find /c /v ""') DO SET "skipcnt=usebackqskip=%%a"
TYPE "%tempfile%c">>"%tempfile%b"
(
FOR /f "%skipcnt%delims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /ad "%%a\*" ^|findstr /v /i /l /g:q22903564.txt'
) DO ECHO(%%a\%%b
)
)>"%tempfile%c"
FOR %%a IN ("%tempfile%c") DO SET /a sizec=%%~za
IF %sizec% gtr 0 GOTO again
(
FOR /f "usebackqdelims=" %%a IN ("%tempfile%b") DO (
FOR /f "delims=" %%b IN (
'dir /b /a-d "%%a\*" 2^>nul'
) DO ECHO(%%a\%%b
)
)>newfile.txt
DEL "%tempfile%*"
GOTO :EOF
This time for sure! (no lion's roar thought)
I realised that the re-filtering against the original tempfileb content was redundant - and removing that meant that the quoting regime to overcome awkward characters could be scaled back. Then in reality the original file was the original addition (tempfilec) to an empty tempfileb, so - a little reorganisation and hand-waving (because 'skip=0' is invalid) and the result is that the only directories that are scanned later are thos that have beed added in the last iteration, optimising the directory-scan methodology.
Now the consequences are that the resultant list will be \a\, \b\, \c\, \a\a1\, \b\b1\, and so on - but a simple sort of the result should take care of that, if required.
This may help: it excludes the terms in line 3 where you see "Common Old"
It creates a list of the folders, filters out the excluded terms, and uses the remaining folders to create the list.
If you only want *.log *.txt files etc then it could be made more efficient again - otherwise remove the *.log *.txt terms in the batch file in line 7
#echo off
dir /b /ad /s /-p > "C:\output.txt"
findstr /v /i "Common Old" "C:\output.txt" >"C:\output2.txt"
del "C:\output.txt"
for /f "usebackq delims=" %%a in ("C:\output2.txt") do (
pushd "%%a"
for /f "delims=" %%b in ('dir *.log *.txt /b /-p /a-d') do >>"C:\output.txt" echo(%%a\%%b
popd
)