Question: I am using Windows XP and need to create a batch file to move tok.filename to filename.tok. 
This works for one file if I type in `fix.bat tok.filename`.

```
set filename=%1
set newname=%filename:~4,45%
ren %1 %newname%.tok

```

I need to type in `fix.bat tok*`, but this puts `tok*` in the filename. 

How do I get it to read all the files into the filename one at a time?

Answer: 
Use a `for` statement.

```
setlocal enabledelayedexpansion

for %%i in (tok.*) do (
  set filename=%%i
  set newname=!filename:~4,45!
  ren %%i !newname!.tok
)

```

Enabling the delayed expansion makes it so that the variables are evaluated at the time they are used.

Alternatively, since you already have a batch file that works, you could write another batch file that uses the `for` statement, which calls your working batch file -- like this:

```
for %%i in (tok.*) do call fix.bat %%i

```

Or you could run it directly from the command line like this:

```
for %i in (tok.*) do call fix.bat %i

```
you can also do the same without delayed expansion (which is slow).
Also, if there is only one dot, without explicitly using lengths of name parts.
%~n expands to filename without extension, and %~x to dot with extension (so I remove dot with `:~1`).

Also, using %\* in for, you may pass arbitrary number of arguments.

And even more. If you add /R bewteen for and %%I (you'll get `for /R %%I`), it will recurse into subdirs also.

Whole batch file:

```
for %%I IN (%*) do call :Rename "%~I"
exit /b

:Rename
    set newname=%~x1
    ren %1 "%~dp1%newname:~1%.%~n1"
exit /b

```