2

I wrote a simple .bat file that appends the string "somethingnew" infront of .txt files:

for %%x in (*.txt) do ren "%%x" "somethingnew%%~nx.txt"

But when I run it, it renames every file correctly, but at the end it renames the first file again.

For example, if there are 2 files 1.txt and 2.txt then this would happen:

  • 1.txt becomes somethingnew1.txt

  • 2.txt becomes somethingnew2.txt

  • somethingnew1.txt becomes somethingnewsomethingnew1.txt

I found similar questions like this one, but instead, the for loops run twice for every file, while here it runs twice for the first file, so I'm not sure what the solution is.

Thanks.

Zero Pancakes
  • 276
  • 2
  • 12
  • Do you have short (8.3) file names enabled? if so, the 8.3 name of the first renamed file (probably `1.txt`, which becomes `somethingnew1.txt`, whose short name is something like `SOMETH~1.TXT`) also matches the pattern `*.txt` and might therefore be renamed twice, because most internal commands (like `dir`, `for`, etc.) that support wildcards match them against both long and short names, and because `for` does not build the file list in advance… – aschipfl Feb 12 '21 at 10:12
  • @aschipfl The `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation` in the registry has a hexadecimal value of `2`. So that means the 8.3 names are disabled? – Zero Pancakes Feb 12 '21 at 10:30
  • Hm… I thought the value to disable is `1`… anyway, note that disabling just prevents future short names but does not clear already present ones… – aschipfl Feb 12 '21 at 21:59

1 Answers1

2

The simple FOR-loop can fetch already renamed files, that's because the for loop take one filename, executes the block code and then take the next filename.

A FOR /F loop will take the complete output of the command, before executing the block code.

for /F "delims=" %%x in ('dir /b *.txt') do (
  ren "%%x" "somethingnew%%~nx.txt"
)
jeb
  • 78,592
  • 17
  • 171
  • 225