0

I've run into the following problem trying to rename several hundred images in a folder (which is a given, I can't influence it).

All files have the structure "name{space}suffix.JPG".
So images can have the same name, but in that case are distinguished by their suffix. E.g.

L083192 (1).JPG L083192 (2).JPG L083192 (3).JPG L083192 (4).JPG 

or

L081473 a.JPG L081473 b.JPG 

The aim is to add a counter (as a prefix) to all images with the same name. I.e.

1_L083192 (1).JPG 1_L083192 (2).JPG 1_L083192 (3).JPG 1_L083192 (4).JPG [..] 16_L081473 a.JPG 16_L081473 b.JPG 

The counter is calculated in a "FOR /F" loop which establishes which names are identical, hence should get the same prefix.
But when I try to add the counter-prefix by applying the following REN command:

ren "%%h*" "!cnt!_%%h*" 

I run into trouble.
(%%h and !cnt! are variables of the "FOR /F" loop)

This is the corresponding output:

L083192 (1).jpg >> 1_L0831921).jpg [i.e. " (" gone missing] [..] L083192 (4).jpg >> 1_L0831924).jpg [id.] 

The two "L081473" files even result in a single output file (without a suffix)!

16_L081473.JPG 

No doubt there is a link with the mechanisms described by dbenham in his extensive post on the REN(AME) command, but I can't work it out for the above case, as I'd expect the original file names to be truncated, rather than some intermediate characters being lost in the process. Maybe the space in the original file name is the reason, though I quoted these file names in the REN command to accommodate spaces? Can anyone explain?

Furthermore, as REN can't seem to produce the looked for result—or can it?—, how can I obtain the aimed for result using plain batch?

I also tried to work around the REN issue by using COPY or XCOPY, but the results are identical. These commands seem to apply the same scheme—as carefully suggested by dbenham in the same post (see the note).


Batch File

FOR /F %%h IN (input.txt) DO ( IF NOT "%%h" == "prev" (set /A cnt+=1) [some more logic..] cd Images ren "%%h*" "!cnt!_%%h*" cd.. [some more logic..] set prev=%%h ) 

Note: I stripped the batch of its additional logic, which a.o. avoids a file being renamed more than once. The "input.txt" contains all occurrences of name only (i.e. without suffix), which is sufficient to calculate the prefix. I could provide a sample file, but did not find how to link it to this message. Besides, that would not allow to replicate the renaming (moreover, "Images" folder is appr. 480 Mb).
The full file names in this folder are taken into account by changing to sub-directory "Images", where the files are waiting to be renamed. (REN works only in the current directory)

1
  • Please include the complete batch file in the question Commented Dec 10, 2019 at 9:47

1 Answer 1

1

You missed, or didn't realize the significance of this paragraph in my RENAME post:

Any name can be broken up into components that are delimited by . Characters may only be appended to or deleted from the end of each component. Characters cannot be deleted from or added to the beginning or middle of a component while preserving the remainder with wildcards. Substitutions are allowed anywhere.

You are trying to add characters to the beginning of the base name, preserving the base name with a wildcard(s). As per my statement above, this cannot be done. You will have to rename each file individually. This should not be particularly difficult. I'm assuming your other logic is correct:

FOR /F %%h IN (input.txt) DO ( IF NOT "%%h" == "prev" (set /A cnt+=1) [some more logic..] cd Images for %%F in ("%%h*") do ren "%%F" "!cnt!_%%F" cd.. [some more logic..] set prev=%%h ) 

Note that the code will fail if %%F contains ! due to delayed expansion being enabled. That can be solved by a bit more code. Better to start out with delayed expansion disabled, and then temporarily enable as needed.

setlocal enableDelayedExpansion for %%N in (!cnt!) do ( endlocal for %%F in ("%%h*") do ren "%%F" "%%N_%%F" ) 
7
  • frankly, I completely missed the significance of the par. you quote. I gave it another try to understand why both ren "L081473 a.JPG" "16_L081473*" and ren "L081473 b.JPG" "16_L081473*" give "16_L081473.JPG" (so the first result is overwritten by the 2nd). 1: [c] source has 9 chars until "." Hence 9 chars of target="16_L08147". 2. [*] Appends all remaining characters (= ".JPG") from source to the target. So I'd get "16_L08147.JPG" for both cases, whereas my test gives "16_L081473.JPG". Where do I go wrong? Commented Dec 11, 2019 at 23:03
  • @WinMike - By the time you reach 3 in the target name, the source base name has been exhausted. So the 3 is appended to the base name. Only . and * in the target can match . in the source. Said another way, all additional characters in target will be appended to the base name until you reach * or . in the target. Commented Dec 11, 2019 at 23:22
  • @WinMike - Within the TargetMask rules, read the definition of c, as well as how c behaves. Your 3 falls into the category of c. Commented Dec 11, 2019 at 23:26
  • As you'll have noted in my previous comment, I assumed that 3 would be left out. Indeed, "Advances the position within the source name as long as the next [source] character is not . " can be done for 9 c's in my example. I had no clue that my 3 falls into the category of c, as this rule says nothing about exhaustion of the base name. Did I miss sth. else in your explanation? Commented Dec 12, 2019 at 0:04
  • @WinMike - Yes, you need to read the TargetMask rules more carefully. I clearly state that all characters that are not *, ?, or . are represented by symbol c in the rules. I assure you the rules fully predict the behavior you are seeing. Commented Dec 12, 2019 at 4:35

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.