How to? Replace in Rename

Oct 18, 2009
351
17
I have a set of files with names in the format SmithAdj20180506.txt and SmithRcpt20180506.txt

I'm trying to add an underscore after Smith. (I'm also hyphenating the dates and adding an underscore before the date, but I have code to handle that.)

I tried RENAME Smith*.txt Smith_*.txt but that results in Smith_dj20180506.txt

I can't just use RENAME Smith???? {etc.} because the filenames aren't all the same length.

It seems I should be able to replace part of a filename with something that's not the same length, basically a REPLACE option that renames the file.

I do know how to pull the files with @findfirst[] and @findnext[], create a string with the new name, and rename the file to the new string, which is what I'm doing with the date portion, but it seems there should be an easier way for simpler things like "replace Smith with Smith_".
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
4,223
78
Albuquerque, NM
prospero.unm.edu
It's not obvious from the help page, but you can use string functions in RENAME's target filename. Double the percent signs, and use an asterisk as the function arg; RENAME will replace the asterisk with the original filename:

Code:
ren *.txt %%@upper[*]
Here's where it gets cute: It doesn't have to be a TCC native function! You can use a user-defined function, or a function from a plugin, or %@EXECSTR a suitably-constructed batch file. Or whatever.
 
May 20, 2008
10,635
82
Syracuse, NY, USA
Or simply @REPLACE. But ... could there be a problem with files which have already been renamed being enumerated again?
Code:
v:\> touch /c SmithAdj20180506.txt
2018-05-30 12:52:10.688  V:\SmithAdj20180506.txt

v:\> do f in Smith*.txt ( ren %f %@replace[Smith,Smith_,%f] )
V:\SmithAdj20180506.txt -> V:\Smith_Adj20180506.txt
     1 file renamed
 

samintz

Scott Mintz
May 20, 2008
1,424
13
Solon, OH, USA
Code:
[C:\TC22]
$ >SmithAdj20180530.txt

[C:\TC22]
$ ren ::(Smith)(Adj.*) ::\1_\2
C:\TC22\SmithAdj20180530.txt -> C:\TC22\Smith_Adj20180530.txt
     1 file renamed
 

samintz

Scott Mintz
May 20, 2008
1,424
13
Solon, OH, USA
Here's one that does the rename of either Adj or Rcpt and adds the dashes for dates:
Code:
[C:\TC22]
$ >SmithAdj20180530.txt

[C:\TC22]
$ >SmithRcpt20180530.txt

[C:\TC22]
$ ren "::(Smith)(Adj|Rcpt)(\d\d\d\d)(\d\d)(\d\d)" ::\1_\2-\3-\4-\5
C:\TC22\SmithAdj20180530.txt -> C:\TC22\Smith_Adj-2018-05-30.txt
C:\TC22\SmithRcpt20180530.txt -> C:\TC22\Smith_Rcpt-2018-05-30.txt
     2 files renamed
 

samintz

Scott Mintz
May 20, 2008
1,424
13
Solon, OH, USA
I just noticed that the REN kept the extension even though I didn't specify it. Is there an implied ".*" at the end of each regex?
 
May 20, 2008
10,635
82
Syracuse, NY, USA
If there are different last names and a limited number of qualifiers (Adj, Rcpt, et c.) ...
Code:
v:\> ren ::(.*)("Adj|Rcpt".*) ::\1_\2
V:\SmithAdj20180506.txt -> V:\Smith_Adj20180506.txt
V:\SmithRcpt20180506.txt -> V:\Smith_Rcpt20180506.txt
     2 files renamed
 
May 20, 2008
10,635
82
Syracuse, NY, USA
Better example:
Code:
v:\> ren ::(.*)("Adj|Rcpt".*) ::\1_\2
V:\JonesAdj20180506.txt -> V:\Jones_Adj20180506.txt
V:\SmithAdj20180506.txt -> V:\Smith_Adj20180506.txt
V:\SmithRcpt20180506.txt -> V:\Smith_Rcpt20180506.txt
     3 files renamed