Need to use a regex in a "for" loop.

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.
#1
Hi,
I need to do a looping on a regex list of filenames. Here's what I'm trying:

for %I in (\.::[A-z]{1}[0-9]{7}.pdf) do copy %I ehs-%I

I get nothing. Goes right back to the prompt.

But, I can do a dir with the above regex and I get all the files listed.

Anyone have any suggestions for something else besides a "for" loop?

Thanks,
Peter
 

samintz

Scott Mintz
May 20, 2008
1,228
11
Solon, OH, USA
#2
You have two issues. You need to put the :: first and you need to enclose
the regex in quotes.

Try this instead:
for %I in ("::\.[A-z]{1}[0-9]{7}.pdf") do copy %I ehs-%I

If I'm interpreting your regex correctly, you want a dot, followed by
exactly 1 letter, followed by exactly 7 digits followed by any character,
followed by "pdf".

So it would match:
.A1234567.pdf
.z76543210pdf

-Scott

pb4072 <> wrote on 07/25/2008 02:22:11 PM:


> Hi,
> I need to do a looping on a regex list of filenames. Here's what I'm
trying:

>
> for %I in (\.::[A-z]{1}[0-9]{7}.pdf) do copy %I ehs-%I
>
> I get nothing. Goes right back to the prompt.
>
> But, I can do a dir with the above regex and I get all the files listed.
>
> Anyone have any suggestions for something else besides a "for" loop?
>
> Thanks,
> Peter
>
>
 
B

BillMc

Guest
#4
. On Fri 25-Jul-08 1:48pm -0600, rconn wrote:
.
. > pb4072 wrote:
.
. >> I need to do a looping on a regex list of filenames. Here's
. >> what I'm trying:
. >>
. >> for %I in (\.::[A-z]{1}[0-9]{7}.pdf) do copy %I ehs-%I
. >>
. >> I get nothing. Goes right back to the prompt.
.
. > Replace the leading "\." (which has no meaning) with ".\".
.
Things aren't working as expected. For example (tcc 9.02):

> for %i in (xray?.txt) do echo %i
xray0.txt
xray1.txt
xray2.txt

However:

> for %i in (::xray.\.txt) do echo %i
::xray.\.txt

Yet:

> dir /b ::xray.\.txt
xray0.txt
xray1.txt
xray2.txt

--
Best regards,
Bill
4nt 8.02.106 / tcmd 9.02.151 cp 2.11.32 on xp pro sp3
 
#5
On Fri, 25 Jul 2008 23:28:31 -0500, BillMc <> wrote:


> > for %i in (::xray.\.txt) do echo %i
> ::xray.\.txt
It might work better with quotes:

v:\> for %f in ("::z.*\.bat") echo %f
V:\ztest.bat
V:\ztest2.bat

And then again, it might not:

v:\> for %f in ("::ztest.\.bat") echo %f
"::ztest.\.bat"
 

rconn

Administrator
Staff member
May 14, 2008
10,192
86
#6
BillMc wrote:

> . On Fri 25-Jul-08 1:48pm -0600, rconn wrote:
> .
> . > pb4072 wrote:
> .
> . >> I need to do a looping on a regex list of filenames. Here's
> . >> what I'm trying:
> . >>
> . >> for %I in (\.::[A-z]{1}[0-9]{7}.pdf) do copy %I ehs-%I
> . >>
> . >> I get nothing. Goes right back to the prompt.
> .
> . > Replace the leading "\." (which has no meaning) with ".\".
> .
> Things aren't working as expected. For example (tcc 9.02):
>
> > for %i in (xray?.txt) do echo %i
> xray0.txt
> xray1.txt
> xray2.txt
>
> However:
>
> > for %i in (::xray.\.txt) do echo %i
> ::xray.\.txt
Remember that FOR isn't necessarily looking for a filename; it could
also be a string set. That's why you need to prefix a path if you want
to look for filenames with regexes.

Rex Conn
JP Software
 
#7
On Sat, 26 Jul 2008 07:44:07 -0500, rconn <> wrote:


>Remember that FOR isn't necessarily looking for a filename; it could
>also be a string set. That's why you need to prefix a path if you want
>to look for filenames with regexes.
How do I get FOR to find the file ztest2.bat with the regex

::ztest.\.bat

I can't get it with or without a path, with or without quotes.

v:\> dir /b zt*.bat
ztest.bat
ztest2.bat

v:\> for %f in ("::ztest.\.bat") echo %f
"::ztest.\.bat"

v:\> for %f in ("::v:\\ztest.\.bat") echo %f
"::v:\\ztest.\.bat"

v:\> for %f in ("v:\::ztest.\.bat") echo %f
"v:\::ztest.\.bat"

v:\> for %f in (::v:\\ztest.\.bat) echo %f
::v:\\ztest.\.bat

v:\> for %f in (v:\::ztest.\.bat) echo %f
v:\::ztest.\.bat
 
B

BillMc

Guest
#8
. On Sat 26-Jul-08 7:44am -0600, rconn wrote:
.
. > Remember that FOR isn't necessarily looking for a filename; it
. > could also be a string set. That's why you need to prefix a
. > path if you want to look for filenames with regexes.
.
OK, I don't need quotes, since no 4nt/tcc special characters are
being used:


> for %i in (.\::xray\d\.txt$) echo %i
.\::xray\d\.txt$

4nt/tcc thinks I'm passing it text. However, if I add what seems
like an unnecessary .*:


> for %i in (.\::.*xray\d\.txt$) echo %i
.\xray0.txt
.\xray1.txt
.\xray2.txt

Although others have reported success with quotes, I've had no
such success.

--
Best regards,
Bill
4nt 8.02.106 / tcmd 9.02.151 cp 2.11.32 on xp pro sp3
 
#9
On Sat, 26 Jul 2008 13:39:52 -0500, BillMc <> wrote:


>Although others have reported success with quotes, I've had no
>such success.
I wasn't really calling it success. It's just that quotes make things work
differently. Consider this:

v:\> for /a: %f in (::ztest[12]\.bat) echo %f

v:\> for /a: %f in ("::ztest[12]\.bat") echo %f
V:\ztest2.bat

What exactly did the quotes do?

And as far as I can tell, anything in FOR's "set" that doesn't contain one of
"*?[" is treated as a literal string. That includes regular expressions (which
are not obliged to contain any of those characters). I tried all I could think
of to get the RE "ztest.\.bat" to work and failed. Regardless of quotes and
paths, it was treated as a literal string.

And it seems that anything in FOR's "set" that **does** contain one of "*?[" is
necessarily considered a file spec.

v:\> for /a: %f in ([ [[ [[[) echo %f

v:\> for /a: %f in (] ]] ]]]) echo %f
]
]]
]]]

It would seem that "::" should be sufficient to get FOR to treat the expression
as a regular expression file spec.

FOR could also use a switch (say /S(trings)) saying that the things in "set" are
strings even if they contain some of "*?[". Maybe I've not tried the right
construct. Is it possible now to get something like this?

for %x in (* ** *** ** *) echo %x
*
**
***
**
*
 
B

BillMc

Guest
#10
. On Sat 26-Jul-08 2:16pm -0600, vefatica wrote:
. > On Sat, 26 Jul 2008 13:39:52 -0500, BillMc <> wrote:
.
. >>Although others have reported success with quotes, I've had no
. >>such success.
.
. > I wasn't really calling it success. It's just that quotes make
. > things work differently. Consider this:
. >
. > v:\> for /a: %f in (::ztest[12]\.bat) echo %f
. >
. > v:\> for /a: %f in ("::ztest[12]\.bat") echo %f
. > V:\ztest2.bat
. >
. > What exactly did the quotes do?

Perhaps I've falsely assumed that you have two files ztest1.bat
and ztest2.bat.

> dir /b ztest*
ztest1.bat
ztest2.bat

I tried your test with and without quotes:

> for %i in ("::ztest[12]\.bat") echo %i

> for %i in (::ztest[12]\.bat) echo %i

No output. Using Rex's trick:

> for %i in (.\::ztest[12]\.bat) echo %i
.\ztest1.bat
.\ztest2.bat

That worked, but replacing `[12]' with `.' doesn't fair so well:

> for %i in (.\::ztest.\.bat) echo %i
.\::ztest.\.bat

Adding the superfluous `.*' does work:

> for %i in (.\::.*ztest.\.bat) echo %i
.\ztest1.bat
.\ztest2.bat

Yet, without the leading `.\':

> for %i in (::.*ztest.\.bat) echo %i

Nothing!

. > And as far as I can tell, anything in FOR's "set" that doesn't
. > contain one of "*?[" is treated as a literal string. That
. > includes regular expressions (which are not obliged to contain
. > any of those characters). I tried all I could think of to get
. > the RE "ztest.\.bat" to work and failed. Regardless of quotes
. > and paths, it was treated as a literal string.

Good observation.

. > And it seems that anything in FOR's "set" that **does** contain
. > one of "*?[" is necessarily considered a file spec.
. >
. > v:\> for /a: %f in ([ [[ [[[) echo %f
. >
. > v:\> for /a: %f in (] ]] ]]]) echo %f
. > ]
. > ]]
. > ]]]

Interesting - the parser is confused by the first example and,
perhaps should produce an error message. The second example
gives results one might expect.

. > It would seem that "::" should be sufficient to get FOR to
. > treat the expression as a regular expression file spec.

I agree.

. > FOR could also use a switch (say /S(trings)) saying that the
. > things in "set" are strings even if they contain some of "*?[".
. > Maybe I've not tried the right construct. Is it possible now
. > to get something like this?
. >
. > for %x in (* ** *** ** *) echo %x
. > *
. > **
. > ***
. > **
. > *

Good example and suggestion.

--
Best regards,
Bill
4nt 8.02.106 / tcmd 9.02.151 cp 2.11.32 on xp pro sp3
 

rconn

Administrator
Staff member
May 14, 2008
10,192
86
#11
vefatica wrote:


> And as far as I can tell, anything in FOR's "set" that doesn't contain
> one of "*?[" is treated as a literal string.
WAD (required for CMD compatibility). See the help file for more details.

If you don't need to run your batch files in CMD, don't use FOR -- use
DO instead.


> FOR could also use a switch (say /S(trings)) saying that the things in
> "set" are
> strings even if they contain some of "*?[". Maybe I've not tried the right
> construct. Is it possible now to get something like this?
>
> for %x in (* ** *** ** *) echo %x
> *
> **
> ***
> **
> *
That would break CMD-compatibility again. Use DO!

Rex Conn
JP Software
 
#12
On Sat, 26 Jul 2008 22:27:21 -0500, rconn <> wrote:


>---Quote---
>> And as far as I can tell, anything in FOR's "set" that doesn't contain
>> one of "*?[" is treated as a literal string.
>---End Quote---
>WAD (required for CMD compatibility). See the help file for more details.
So regular expressions will only work is they contain wildcard characters?

>
>If you don't need to run your batch files in CMD, don't use FOR -- use
>DO instead.
Can't use DO on the command line.


>---Quote---
>> FOR could also use a switch (say /S(trings)) saying that the things in
>> "set" are
>> strings even if they contain some of "*?[". Maybe I've not tried the right
>> construct. Is it possible now to get something like this?
>>
>> for %x in (* ** *** ** *) echo %x
>> *
>> **
>> ***
>> **
>> *
>---End Quote---
>That would break CMD-compatibility again. Use DO!
I don't see how a switch to force strings would break CMD-compatibility.

for /S %x in (* ** *** ** *) echo %x
*
**
***
**
*

There's a lot of the alphabet left for FOR to use for options. A /X (regex)
switch seems reasonable too, especially if (as it stands) regexes are limited
and cumbersome to use. The way regexes work in FOR's "set" is really mysterious
... the business of prepending a path ... quotes causing different behavior ...
the need for a wildcard character ... I just don't get it. It would be nice if
regex matching were automatic (either because of "::" or a switch) and if they
worked just like wildcard specs.
 

rconn

Administrator
Staff member
May 14, 2008
10,192
86
#13
vefatica wrote:

> On Sat, 26 Jul 2008 22:27:21 -0500, rconn <> wrote:
>
>
> Quote:
> >---Quote---
> >> And as far as I can tell, anything in FOR's "set" that doesn't contain
> >> one of "*?[" is treated as a literal string.
> >---End Quote---
> >WAD (required for CMD compatibility). See the help file for more details.
>
> So regular expressions will only work is they contain wildcard characters?
That's correct.


> Quote:
> >
> >If you don't need to run your batch files in CMD, don't use FOR -- use
> >DO instead.
>
> Can't use DO on the command line.
Put it in a batch file.


> Quote:
> There's a lot of the alphabet left for FOR to use for options.
I will not be adding features to FOR. The availability of switches
isn't the problem, it's the FOR parser -- which is almost impossibly
complex as-is in order to support the CMD syntax.

Rex Conn
JP Software
 
#14
vefatica wrote:
| FOR could also use a switch (say /S(trings)) saying that the things
| in "set" are strings even if they contain some of "*?[". Maybe I've
| not tried the right construct. Is it possible now to get something
| like this?

Actually, using a single regular expression in FOR makes no sense when you
use intend to use a literal set, since it would be executed for a single
value, i.e., the REGEX itself. Multiple REGEXes as the set make sense only
when you want to execute the "DO command" for each literal value of the
REGEX, i.e., the command is to be repeated for multiple REGEXes, and REGEX
evaluation is done only in the command, a highly artificial situation
(though users like Vince and I may find use for it).

Rex, does specifying /A: force the set to be considered directory entry
specification? If so, the option could be used to force interpretation of
REGEXes in the set not to be literal, and new suboption /A- or /A:- could be
forcing interpretation as literal strings.
--
Steve
 
#15
rconn wrote:
| WAD (required for CMD compatibility). See the help file for more
| details.
|
| If you don't need to run your batch files in CMD, don't use FOR -- use
| DO instead.

No interactive DO yet, is there? What do you do at the command prompt?
--
Steve
 

rconn

Administrator
Staff member
May 14, 2008
10,192
86
#16
Steve Fábián wrote:

> rconn wrote:
> | WAD (required for CMD compatibility). See the help file for more
> | details.
> |
> | If you don't need to run your batch files in CMD, don't use FOR -- use
> | DO instead.
>
> No interactive DO yet, is there? What do you do at the command prompt?
You write a batch file and run it at the command prompt -- or in the
batch debugger, which is easier & more powerful than trying to run a
complex command at the command prompt.

Rex Conn
JP Software
 
#17
> You write a batch file and run it at the command prompt -- or in the
> batch debugger, which is easier & more powerful than trying to run a
> complex command at the command prompt.
The ability to do things directly from the command line is why I use perl -e
multiple times a day. I've typed in countless FOR loops at the command line.
For one-shot tools, until the perl -e commands or FOR loops get very
complex, I simply up-arrow iterate over the line I'm building.

There must be a compelling reason to prohibit the usage at the command line
-- your position is that it is easier and more powerful for the user to
create a one-shot temporary file, but this user (and it sounds like Steve,
also) does not agree.

In fact, I use precious few _new_ batch files, which is why I don't use the
DO loop. As soon as it becomes available at the command prompt, I'll use it.
The old batch files I do use are almost all required to be CMD compatible,
so the one place I could use DO is the interactive prompt.

In order to use DO: You are suggesting I should fire up the editor, make a
new batch file, type in my desired DO, switch back to TCC, run the tool
once, delete the batch file, close the editor. If DO were available at the
prompt, I would eliminate most of those steps.

What is the compelling reason to prohibit certain constructs at the
interactive prompt? My own guess would be the parsing nightmares that you've
described.
 

rconn

Administrator
Staff member
May 14, 2008
10,192
86
#18
Jim Cook wrote:

>
> In order to use DO: You are suggesting I should fire up the editor, make a
> new batch file, type in my desired DO, switch back to TCC, run the tool
> once, delete the batch file, close the editor. If DO were available at the
> prompt, I would eliminate most of those steps.
No, I'm suggesting you click on the toolbar button to invoke the
debugger, type the command, and run it.


> What is the compelling reason to prohibit certain constructs at the
> interactive prompt? My own guess would be the parsing nightmares that you've
> described.
The compelling reason is that changing it will break existing batch
files written for CMD. FOR cannot be extended without creating ongoing
compatibility issues. (We already get twice as many complaints about
FOR not being identical to CMD as everything else put together.)

Rex Conn
JP Software
 
#20
: In order to use DO: You are suggesting I should fire up the editor, make a
: new batch file, type in my desired DO, switch back to TCC, run the tool
: once, delete the batch file, close the editor. If DO were available at the
: prompt, I would eliminate most of those steps.

or you could use : copy con test.btm
: do what ever you want
Ctrl Z
no editor started but file test.btm created. I use this approach when copy &
paste from forum to test someone else's script.
and because I hated edlin way back then.
 
#21
On Sun, 27 Jul 2008 10:11:00 -0500, rconn <> wrote:


>No, I'm suggesting you click on the toolbar button to invoke the
>debugger, type the command, and run it.
It's not as simple as that.

That process will involve several or all of

BDEBUGGER
a "create file" dialog
"start debugging"
a "save file" dialog
a "replace file" dialog
one or more buttons to get it to actually execute

If you could get that down to (as you suggested)

BDEBUGGER
type the command
press "Run"

that would be great (I'd actually use it).

How about a simple "Run" button and an OPTION option "Autosave on Run" (save
with the given or default name and no "Replace" prompting)? Those, together
with "ALIAS DB BDEBUGGER /C" (even @@KEY) would make db/type/run actually be as
easy as you made it sound. And to get a little fancy, the "Run" button could
even ignore breakpoints.
 
#22
On Sun, 27 Jul 2008 11:29:37 -0500, vefatica <> wrote:


>How about a simple "Run" button and an OPTION option "Autosave on Run" (save
>with the given or default name and no "Replace" prompting)? Those, together
>with "ALIAS DB BDEBUGGER /C" (even @@KEY) would make db/type/run actually be as
>easy as you made it sound. And to get a little fancy, the "Run" button could
>even ignore breakpoints.
It would also be convenient if, when using an enduring debugger (/K), "Run"
would leave the console (or TCMD) in the foreground (so one could see the
output).
 
#23
rconn wrote:
| Jim Cook wrote:
|
|
| ---Quote---
||
|| In order to use DO: You are suggesting I should fire up the editor,
|| make a new batch file, type in my desired DO, switch back to TCC,
|| run the tool once, delete the batch file, close the editor. If DO
|| were available at the prompt, I would eliminate most of those steps.
| ---End Quote---
| No, I'm suggesting you click on the toolbar button to invoke the
| debugger, type the command, and run it.

I don't see toolbar buttons in TCC (stand-alone). I rarely use more than one
concurrent instance of the command processor, and I don't need the directory
displays, so I have no reason under normal conditions to run TCMD.
|
| ---Quote---
|| What is the compelling reason to prohibit certain constructs at the
|| interactive prompt? My own guess would be the parsing nightmares
|| that you've described.
| ---End Quote---
| The compelling reason is that changing it will break existing batch
| files written for CMD. FOR cannot be extended without creating
| ongoing compatibility issues. (We already get twice as many
| complaints about
| FOR not being identical to CMD as everything else put together.)

1/ AFAIK regular expressions (which are the main reason for this thread) are
not available in CMD, so anything to support them in TCC is already
incompatible with CMD.

2/ How would an additional option, not currently in existence, decrease CMD
compatibility? Do you get complaints about TCC features not available in
CMD?
--
Steve
 

rconn

Administrator
Staff member
May 14, 2008
10,192
86
#24
Steve Fábián wrote:


> | ---Quote---
> || What is the compelling reason to prohibit certain constructs at the
> || interactive prompt? My own guess would be the parsing nightmares
> || that you've described.
> | ---End Quote---
> | The compelling reason is that changing it will break existing batch
> | files written for CMD. FOR cannot be extended without creating
> | ongoing compatibility issues. (We already get twice as many
> | complaints about
> | FOR not being identical to CMD as everything else put together.)
>
> 1/ AFAIK regular expressions (which are the main reason for this thread)
> are
> not available in CMD, so anything to support them in TCC is already
> incompatible with CMD.
Right, which is why using them in a FOR argument cannot be interpreted
as a filename wildcard, as there are existing batch files with an
embedded "::" meaning "string, not filename".


> 2/ How would an additional option, not currently in existence, decrease CMD
> compatibility? Do you get complaints about TCC features not available in
> CMD?
You're missing my point -- ANYTHING added to FOR at this point decreases
CMD compatibility, because any new options require bending (or breaking)
the existing parser.

If you don't want any compatibility with CMD, write a FOR plugin.

Rex Conn
JP Software
 
#25
For writing/testing little batch files (DO routines, maybe, where FOR won't work) I wrote a little plugin (QBAT.BAT). Please check out this JPG and make comments/suggestions (don't ask for much; it's just a dialog box with an edit control).

ftp://lucky.syr.edu/4plugins/qbat.jpg

The JPG doesn't look very good in a browser. It should be pretty much self-explanatory ... edit/run ... edit/run ... et c. For simple things, it's a lot easier than the debugger.

You can start it with a [path\]filename (existing or not) ... else it uses/creates "QBAT.BAT" in the current directory. The plugin itself (QBAT.DLL, 4KB) is also on the FTP site; it's very barebones.

Syntax: QBAT [batfilename]

I'll try attaching the JPG to this post (the BBS says it did it but it doesn't look good in a browser).
 

Attachments

Jun 7, 2008
96
3
#26
#27
On Mon, 28 Jul 2008 02:03:22 -0500, DMcCunney <> wrote:


>> Attached to this message is qbat.jpg (http://jpsoft.com/forums/attachment.php?attachmentid=5&d=1217219229)
>---End Quote---
>Which browser? Looks fine here both in the link to the original file
>and on the board, using Firefox 3.0.
FireFox 2.0.0.15. The image is the size of my desktop. Is there a way to get
FF to show it un-scaled and with scrollbars?
 
#28
Nope. Sorry. None of these solutions work. I get nothing. I just tried it with a simple "echo." I guess I'll make a batch file and use "do."

for %I in ("::\.[A-z]{1}[0-9]{7}.pdf") do copy %I ehs-%I
for %I in ("::"\."[A-z]{1}[0-9]{7}.pdf") do copy %I ehs-%I

-Peter


You have two issues. You need to put the :: first and you need to enclose
the regex in quotes.

Try this instead:
for %I in ("::\.[A-z]{1}[0-9]{7}.pdf") do copy %I ehs-%I

If I'm interpreting your regex correctly, you want a dot, followed by
exactly 1 letter, followed by exactly 7 digits followed by any character,
followed by "pdf".

So it would match:
.A1234567.pdf
.z76543210pdf

-Scott

pb4072 <> wrote on 07/25/2008 02:22:11 PM:



trying:
 

rconn

Administrator
Staff member
May 14, 2008
10,192
86
#29
pb4072 wrote:

> Nope. Sorry. None of these solutions work. I get nothing. I just tried
> it with a simple "echo." I guess I'll make a batch file and use "do."
>
> for %I in ("::\.[A-z]{1}[0-9]{7}.pdf") do copy %I ehs-%I
> for %I in ("::"\."[A-z]{1}[0-9]{7}.pdf") do copy %I ehs-%I
"\." is meaningless; you need to use ".\" instead:

for %I in (".\::[A-z]{1}[0-9]{7}.pdf") do copy %I ehs-%I

But using DO would be a much better (and more flexible/powerful)
alternative.

Rex Conn
JP Software
 
#30
Vince,

I tried loading the QBAT plugin. When I execute QBAT, a task opens but I
see nothing on the screen and can recover only by killing the TCC task
in which QBAT was run.

-- Jay