Regular expression groups

Jan 19, 2011
581
10
Norman, OK
#1
Is it possible to use back-references/grouping in commands? I know that I can use them as selectors but what about as replacements?

For instance, I have files named
Code:
a1.txt
b2.txt
c3.txt
d4.txt
and I'd like to rename them
Code:
1a.txt
2b.txt
3c.txt
4d.txt
Using regular expressions it should be as simple as
Code:
ren ::(.)(.)\.txt \2\1.txt
but it doesn't work. Ideas? What about using FOR or DO?
 
#2
For %F in (??.txt) Do (Ren %F %@Instr[1,1,%F]%@Left[1,%F].%@Ext[%F])


Tested and works; does not touch file names that are more than 3 characters, however does destroy single-character file names (you can use an @If in the "do" portion to test that the file names are exactly 2 characters long):

For %F in (??.txt) Do (%@If[%@Len[%F] == 6,ren %F %@Instr[1,1,%F]%@Left[1,%F].%@Ext[%F]])

Also tested.

- Dan
 
Jan 19, 2011
581
10
Norman, OK
#3
Thanks Dan,

However, I really didn't need to do that specific task. I was providing a generic example.

With regular expressions, for example using
Code:
ren "::(.*?)\b(.)\b(.*?)\.txt" "\3 \1 \2.txt"
should be able to change
Code:
John Q Smith.txt
to
Code:
Smith John Q.txt
Being able to use regular expressions in this way would be AWESOME.
 
Feb 23, 2012
238
3
#5
True, the @XREPLACE function could solve this problem, but it is still requires a somewhat roundabout and non-straightforward syntax, because it would have to packaged within some sort of loop, rather than being run directly as a REN command.
I noticed that a couple of years ago vefatica suggested adding a /X option to REN which would do just this - it would treat the source and target names as regular expressions such that the target pattern would be able to include backreferences to the source name (see here: http://jpsoft.com/forums/threads/batch-renames.1521/)
That would provide a much more elegant and straightforward solution to JohnQSmith's query.
Indeed, I would use it often, too (right now I use the free command-line utility BulkRenameUtility to do bulk regex-based renames, but the latter utility has serious bugs and shortcomings when it comes to applying regex expressions to unicode filenames - it will cause serious damage to non-English filenames - and hence I'd much rather have a regex rename in TCC where unicode is fully supported).
Given the number of threads that have raised this issue (in addition to this one and the aformentioned one, see also: http://jpsoft.com/forums/threads/regex-rename.2416/), I think that there is sufficient interest. Unless there is any objection, I'll add this on the feature request site later today. If all of us regex-addicts vote on the feature-request site, perhaps we'll see it soon in TCC...

@XREPLACE, in Vincent's 4UTILS, might be what you're looking for.
 
Jan 19, 2011
581
10
Norman, OK
#6
@XREPLACE, in Vincent's 4UTILS, might be what you're looking for.
Sorry for not replying sooner... Thanks Charles. I've been playing around with it. Working to create aliases to simplify using it.

I think that there is sufficient interest. Unless there is any objection, I'll add this on the feature request site later today. If all of us regex-addicts vote on the feature-request site, perhaps we'll see it soon in TCC...
It's got my vote.
 
Jan 19, 2011
581
10
Norman, OK
#7
OK. After quite a bit of tweaking and massaging, I finally got a generic regex command created using Vincent Fatica's 4utils plugin. I've only tried it using COPY and REN since that's where I needed it, but I'm sure it'll work on other commands. Just remember, it doesn't do paths.

Usage:
Code:
xcmd <command> <input> <output>
For instance... if I have a bunch of files named in the style of "Firstname X Lastname.doc" and want to rename them in the style of "Lastname, Firstname X.doc", then the command would be
Code:
xcmd ren "(.*? .) (.*?)\.doc" "\2, \1.doc"
Caveat emptor, but it works for me. So, here's the alias.
Code:
xcmd=for /w %i in (%@quote[::%@unquote[%2]]) %1 %@quote[%@filename[%i]] %@quote[%@xreplace[%@quote[%@unquote[%2]],%@quote[%@unquote[%3]],%@quote[%@filename[%i]]]]
Remember, you can't just copy, paste, and run the alias at the TCC prompt unless you double all the % signs first.
 
Feb 23, 2012
238
3
#8
Nice tweak, JohnQSmith! Still, internal REN support for regexes would be much more ideal - for instance, it would then allow access to the /N option to preview the results, something that is quite important when doing bulk renames of this nature.
I've opened up a feature request for this; please vote if you identify with the need and usefulness for full regex support in REN. The support request is here:
http://jpsoft.uservoice.com/forums/...support-regex-backreferences-for-bulk-renames
 

samintz

Scott Mintz
May 20, 2008
1,294
11
Solon, OH, USA
#9
Avi, I added my vote to your feature request. However, I believe one of the arguments against doing the back references is due to the parsing difficulty of knowing when you are using a back reference vs. using an actual directory named \1 or \2. So there will have to be some kind of syntactic sugar to make it possible. Personally, I doubt there are very many directories out there named \1 or \2. But, Rex will need to account for them nonetheless. It could be as simple as doubling the backslashes.

-Scott
 
#10
Code:
v:\> echo %@xreplace[o,\\1,foo]
f\1\1
Avi, I added my vote to your feature request. However, I believe one of the arguments against doing the back references is due to the parsing difficulty of knowing when you are using a back reference vs. using an actual directory named \1 or \2. So there will have to be some kind of syntactic sugar to make it possible. Personally, I doubt there are very many directories out there named \1 or \2. But, Rex will need to account for them nonetheless. It could be as simple as doubling the backslashes.
Of course it's that simple and that's built into REs.

It's still doing it. The insertion point was down here whan I inserted code (and look where it went).

So many have asked for this. I'd be glad to send Rex the code for @XREPLACE[] as a starting point. I'd also like a command to do the same thing (like SED's "s" command) in a pipe.
 
Feb 23, 2012
238
3
#11
Hi Vince,
So how *do* you parse the regex expressions in XREPLACE? Are you using the Oniguruma libraries like the rest of TCC, or do you have your own regex library that you use?
- Avi
 
#14
Code:
v:\> dir ftp://jpsoft.com
TCC: Timeout. "jpsoft.com"
 
v:\> dir ftp://jpsoft.com/sdk
 
TCC: Timeout. "jpsoft.com"
TCC: Timeout. "jpsoft.com"
TCC: (Sys) The system cannot find the file specified.
"ftp://jpsoft.com/sdk"
                0 bytes in 0 files and 0 dirs
 
v:\> copy "ftp://jpsoft.com/sdk/sdk.zip"
TCC: Timeout. "jpsoft.com"
TCC: Timeout. "jpsoft.com"
TCC: (Sys) The system cannot find the file specified.
"ftp://jpsoft.com/sdk/sdk.zip"
    0 files copied
Vincent, where are you finding that?
It's on the ftp server, \sdk\sdk.zip. I just got it with an old CuteFTP but I can't make any headway getting it with TCC. Over and over I get the likes of this:
[Inserting code here] Damn it!
 
Jan 19, 2011
581
10
Norman, OK
#16
It's on the ftp server, \sdk\sdk.zip. I just got it with an old CuteFTP but I can't make any headway getting it with TCC. Over and over I get the likes of this:
[Inserting code here] Damn it!
I seem to recall a previous discussion about having to actually include the "ftp" in front of the jpsoft.

Try this instead...
Code:
copy "ftp://ftp.jpsoft.com/sdk/sdk.zip"
Edit:
Ahh, I see you figured it out in a different thread.