FOR /R puzzler? (wildcarded folders only, e.g. A*)

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
MicrosoftIsKillingMe
Posts: 55
Joined: 11 Dec 2017 09:08

FOR /R puzzler? (wildcarded folders only, e.g. A*)

#1 Post by MicrosoftIsKillingMe » 15 Jan 2024 03:34

FOR /R puzzler? (wildcarded folders only, e.g. A*)

I have c:\JOE\ALAN, c:\JOE\ALBERT, c:\JOE\ANNA, c:\JOE\BOB
Launching from \JOE\, I want to findstr every file hat.txt that contains the string {cat} (no braces),
but only for DIRs that begin with the letter A; and include the DIR in the output, perhaps like this:
c:\JOE\ALAN\hat.txt I am a cat
c:\JOE\ANNA\hat.txt I am not a cat
(I do not want {c:\JOE\BOB\hat.txt I be cat} because BOB\ doesn't begin with A)
This output is also fine:
ALAN\hat.txt I am a cat
ANNA\hat.txt I am not a cat

I have foo.bat containing something like this:

Code: Select all

findstr /i /c:%1 %2
My thoughts were something like

Code: Select all

FOR %%a in (A*.) do (foo.bat cat %%a\hat.txt)
but I stumbled with the wildcard expression which seems to ignore DIRs.

I thought about FOR /R %%a in (hat.txt) do (foo.bat cat)
but I only want to process DIRs beginning with letter A.

Is this practical? Note,
- Everything (including the foo.bat wrapper) will be in a .bat, ergo the %%.
- I want the DIR name, not the filename on the output (I don't mind filename also though).
- I don't prefer, but don't mind if the DIR is on a separate line than the FINDSTR string output.
- FINDSTR /S may figure into the solution, but again I want to restrict which DIRs are searched.
- A clever solution might redirect or pipe feeding FINDSTR /D (or /F ?) but I avoid redirection, just my quirk, although I'm happy to append 2>NUL to suppress error messages (inside the .bat on the FINDSTR, not on the .bat issuance itself, right?)

I put a lot of details here so thanks just for reading through. I have found every participant here to be a great human being in their dedication to performance and excellence and accuracy and clarity, and that takes devoted effort which I am humbly grateful for.

MicrosoftIsKillingMe
Posts: 55
Joined: 11 Dec 2017 09:08

Re: FOR /R puzzler? (wildcarded folders only, e.g. A*)

#2 Post by MicrosoftIsKillingMe » 15 Jan 2024 05:32

Let me add, about redirection, some of you who are highly comfortable and proficient with redirection and piping might be thinking "he's shooting himself in the foot because piping (DIR A*.) is certainly the expedient answer". If so, okay, I'll do it the "right" way. It's just that if I can simply add or change one command or parameter in one of the 2 things I attempted (or FIND /S somehow), it would be easier for me to mentally process and maintain. I've seen some of the redirection done here and to me it's mindspinningly complex, though some of you guys can do those things in your sleep! So I'm not trying to be obstinate. Just expressing my comfort level.

(I don't even know whether the 2>NUL goes after the FINDSTR, or after the FOR that calls foo.bat, or via
MYBAT.BAT 2>NUL where MYBAT has the FOR command! I'm just obeying the advice of the movie character Dirty Harry: "A man's got to know his limitations". I've learned that I get in trouble doing things that I don't have a solid reliable grounding in. Sometimes one has to say, "Sure, rewiring that electrical outlet looks easy on youTube, but that's something that should be left to experts" :) )

One more thought: if I'm willing to sacrifice all error messages with 2>NUL anyway, then I don't mind A*. not only catching dirs like ALAN but also abc., an actual "non-dir" file. If the logic attempts to process abc.\hat.txt I'm just assuming it's a harmless error that I can invisibly ignore due to discarding error output. It feels like bad form, and if there were a thousand non-dir A*. files there might be noticeable inefficiency, but I can live with it for this application, if that is simpler than filtering out non-dir files beginning with A.

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: FOR /R puzzler? (wildcarded folders only, e.g. A*)

#3 Post by Squashman » 15 Jan 2024 10:17

If you want the specific directories only then code for that using the DIR command.

Code: Select all

FOR /F "delims=" %%G IN ('dir A* /AD /B') DO findstr /IC:"cat" "%%G\hat.txt"

MicrosoftIsKillingMe
Posts: 55
Joined: 11 Dec 2017 09:08

Re: FOR /R puzzler? (wildcarded folders only, e.g. A*)

#4 Post by MicrosoftIsKillingMe » 15 Jan 2024 11:28

I feel short of words in responding. I consulted AI, and the answer is...
(As expressed by character Jeff Spicoli of "Fast Times at Ridgemont High") "Awesome! Totally awesome!"

That's everything that I could ask for AFAIAC. I incorporated in my .bat calling .bat and success. Solved.

I observed something interesting; with one master .bat containing the for, and that for executing do foo.bat "%%G" (the FINDSTR resides in foo.bat), and having ECHO OFF on each .bat, it was still very noisy. Changing that to do CALL foo.bat "%%G" silenced it. Normally I only remember to insert CALL when something performs only one "sub" bat invocation and never returns, but this one does return even without CALL, and does loop through all cases; but I suppose the new instances lose the ECHO OFF whereas CALL preserves it. That may be instantly logical to others but I just fumbled my way onto seeing that.

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: FOR /R puzzler? (wildcarded folders only, e.g. A*)

#5 Post by jeb » 16 Jan 2024 05:51

MicrosoftIsKillingMe wrote:
15 Jan 2024 11:28
I observed something interesting; with one master .bat containing the for, and that for executing do foo.bat "%%G" (the FINDSTR resides in foo.bat), and having ECHO OFF on each .bat, it was still very noisy. Changing that to do CALL foo.bat "%%G" silenced it. Normally I only remember to insert CALL when something performs only one "sub" bat invocation and never returns, but this one does return even without CALL, and does loop through all cases; but I suppose the new instances lose the ECHO OFF whereas CALL preserves it. That may be instantly logical to others but I just fumbled my way onto seein
The effect is known, but it's not very obvious.
Starting a batch file without call will result in not returning to the caller (in reality the caller transfers the flow to the called batch file).
But in your case it looks like it returns to the caller, because the for loop still executes all required loops.
But when there is a command after the loop it will not be executed.

Code: Select all

FOR %%a in (A*.) do (
  foo.bat cat %%a\hat.txt
)
echo You will never see this line
The FOR-Loop or any other parenthesis block forces this behavior. The block is strong enough to executes code even when there is no more caller reference.
But in that case even the batch file context is lost, the context switched back to the command line context, with some strange effect like.
echo switched back to ON, %0 or %~f0 isn't known in command line context, ...

Code: Select all

@echo off

for /L %%n in (1 1 2) do (
  call echo #1 %%~f0
  dummy.bat
  call echo #2 %%~f0
)
echo END
output wrote:#1 C:\Users\jeb\bat\t1.bat
This is dummy.bat args=""
#2 %~f0

jeb@DESKTOP-T9D9H7D C:\Users\jeb\bat>(
call echo #1 %~f0
dummy.bat
call echo #2 %~f0
)
#1 %~f0
This is dummy.bat args=""
#2 %~f0
The CALL command ensures that the caller is properly stored on the call stack and that everything runs smoothly

MicrosoftIsKillingMe
Posts: 55
Joined: 11 Dec 2017 09:08

Re: FOR /R puzzler? (wildcarded folders only, e.g. A*)

#6 Post by MicrosoftIsKillingMe » 16 Jan 2024 15:52

That is also valuable and instructive, and provides rich context and valuable, instructive examples. Thank you.

Post Reply