0

I have hundreds of files I want to rename to match a new convention. Current convention is AA.BBBB.XXX I want to change it to BBBB.AA.XXX

I've cd'd into the folder which holds all of these files. I thought I could simply loop through the files and grab the substrings needed to reconstruct the file name. The problem is that %name% appears to be empty when echoed.

for %%f in (*) do (
    set name=%%f
    set arr=%name:~0,3%
    set sta=%name:~3,5%
    set rest=%name:~8,26%
    set new=%sta%%arr%%rest%
    echo f: %%f
    echo name: %name%
    echo arr: %arr%
    echo sta: %sta%
    echo rest: %rest%
    echo new: %new%
    set
    pause
)

As you can see at the bottom I called 'set' so I can see what's going on with these variables. It shows %name% to be equal to what I expect, yet it shows empty when echoed and my other variable assignments are unable to pull substrings from %name%.

  • Is this something that you are going to do once? Or it is something that needs to be automated? If it is a one-shot task, then there are many free utilities (on Windows) that would do the rename. For instance http://regexrenamer.sourceforge.net/ – RobertBaron May 22 '19 at 23:08
  • You've fallen into the [delayed expansion](https://stackoverflow.com/questions/10558316/example-of-delayed-expansion-in-batch-file) trap, like many before you. Add `setlocal enabledelayedexpansion` to your script and replace `%name%` with `!name!`. – BDM May 23 '19 at 00:00
  • Possible duplicate of [How to set a variable inside a loop for /F](https://stackoverflow.com/questions/13805187/how-to-set-a-variable-inside-a-loop-for-f) – BDM May 23 '19 at 00:50
  • @Robert This will have to be repeated on occasion. If I can't get it to work after playing with delayed expansion I will try your link. Thank you! – yuehan96 May 23 '19 at 17:34
  • Regex Renamer actually remembers the regular expression that you enter, and so the regular expression is available whenever you reopen the application. If I remember correctly, it also remembers the last folder you were in. – RobertBaron May 23 '19 at 17:40
  • @Robert enabling delayed expansion fixed the problem for me. But Regex Renamer sounds super handy, I'll check it out anyway – yuehan96 May 23 '19 at 18:17

3 Answers3

1

In case the dots in your convention are meant to be literal,
you can use them to split the Names with a for /f and reorder the parts.

Edit: due to Compos hint changed the iterating for to check convention with a RegEx

:: Q:\Test\2019\05\23\SO_56266054.cmd
@Echo off
PushD "A:\Test"

For /f "delims=" %%F in ('Dir /B "??.????.*"^|findstr "^..\.....\.*"'
  ) do For /F "tokens=1,2*delims=." %%A in ("%%F"
    ) Do Echo Ren "%%F" "%%B.%%A.%%C"

PopD

If the output looks OK, remove the echo.

Sample output:

> Q:\Test\2019\05\23\SO_56266054.cmd
Ren "AA.BBBB.XXX" "BBBB.AA.XXX"
Ren "CC.DDDD.YYYY" "DDDD.CC.YYYY"
Ren "EE.FFFF.ZZZZZ" "FFFF.EE.ZZZZZ"
  • @yuehan96, just bear in mind that the `??.????.*` in this case is a little greedy/unpredictable in that it will pick up, `A.BBB.CC.txt`, `A.BBBB.txt,` and `AA.BB.C.txt` and other combinations, as well as `AA.BBBB.txt` etc. When used with the `Dir` command, it also suffers the same issue, _I think_. The `Where` command, as I used in my answer, sees `?` as a single character only, so if there's a chance that you may have files which do not match the spec in the same directory, you may need to adjust it accordingly. – Compo May 23 '19 at 20:09
  • @Compo Albeit IMO a minor risk, I changed the iterating for. OP seems quite unresponsive. No accept, no votes. –  May 24 '19 at 20:51
0

Here's one idea, using delayed expansion:

@Echo Off
For /F Delims^=^ EOL^= %%A In ('Where ".:??.????.???" 2^>NUL') Do (
    Set "_=%%~nA"
    SetLocal EnableDelayedExpansion
    Ren "%%A" "!_:~-4!.!_:~,2!%%~xA"
    EndLocal
)
Compo
  • 36,585
  • 5
  • 27
  • 39
0

Your approach is fine, if a little bit clumsy.

But I think you need delayed expansion, and using ! instead of %

setlocal enabledelayedexpansion
for %%f in (*) do (
    set name=%%f
    set arr=!name:~0,3!
    set sta=!name:~3,5!
    set rest=!name:~8,26!
    set new=!sta!!arr!!rest!
    echo f: %%f
    echo name: !name!
    echo arr: !arr!
    echo sta: !sta!
    echo rest: !rest!
    echo new: !new!
    set
    pause
)
abelenky
  • 63,815
  • 23
  • 109
  • 159