3 Comments »

One of the posts that keeps coming up in comments and email is the one I wrote about using the FOR command to rename files from the command line. I just got another request about it that intrigued me: how can you rename files that have spaces in them? It’s not just that you want to slap the file name in quotes; you want to actually extract part of the filename to reuse in the new filename. Hmmm.

After a bit of searching, and experimenting, I have it.

The Problem

The first thing I like to do is create a directory with a few empty files in it, named appropriately. In this case, I have:

Directory of F:\ToDo\test
Sun 10 Jun 07 11:19 <DIR> .
Sun 10 Jun 07 11:19 <DIR> ..
Sun 10 Jun 07 11:19 0 abc xxx 123.txt
Sun 10 Jun 07 11:19 0 abc xxx 456.txt
2 File(s) 0 bytes

The request is to rename the file “abc xxx 123.txt” to “123.txt”.

Testing Your Expression

Looking at it, it doesn’t seem too bad, but the way I’ve explained it in the original post won’t work. That’s because there, I have one delimiter, “.”, which will end up breaking the file name into two chunks: “abc xxx 123″ and “txt”. That doesn’t quite help. I need to break it into more chunks.

So, I did some searching and testing, and have come up with a way to break the file name into four chunks. One thing I do is run a non-destructive test, to see how my expression works. If you use the FOR command with a benign “do” section, like “echo”, then you can see how the filenames in your directory are broken up.

For instance, I’ve come up with the command:

for /f “tokens=1,2,3,4 delims=. ” %i in (’dir abc*.txt /b’) do echo %i-%j-%k-%l

Here, I want to break each file name into four parts, using the “.” and ” ” as delimiters. The stuff in the brackets is telling the for command what to read though; in this case, a bare directory listing, filtered on text files that begin with “abc”. I could have just done ‘dir *.* /b’ in here, but I didn’t want to mess up another other files. You can see my original post for more information about the FOR command.

At the end of the command, you can see my non-destructive test - simply echoing the four parts of the file name, with a hyphen in between in each. The results of this command are:

As you can see, this command breaks up the filenames perfectly.

The Solution

Now that I know that my tokens are being broken up properly, I can run the actually renaming command. In this case, the filename “abc xxx 123.txt” should be renamed to “abc.txt”. This command will do it for you:

for /f “tokens=1,2,3,4 delims=. ” %i in (’dir abc*.txt /b’) do rename “%i %j %k.%l” “%k.%l”

And here are the results:

And that’s all there is to it. It never ceases to amaze me how powerful using the FOR command is. If you play around with it, you can figure out all sorts of interesting things :)

10 Comments »

Although I mess around with DOS batch files and the command line, I’ve never really gotten into the FOR command. Wow, what a powerful little puppy that is. I read a post at LifeHacker today that has inspired me to figure out how to use the FOR command to handle a little housekeeping task that I’ve never figured out how to do. Until today.And even if you don’t need to rename files, there may be some other housekeeping chores that this can help you with. Actually, the FOR command is really quite powerful; it can even look into files, which opens up all sorts of possibilities for use.

Setup

Let’s say that I’ve got some files that I’ve tacked .del onto, so that I know that I don’t want them any more. For example:

Directory of F:\ToDo\archive

Wed 15 Nov 06 12:13 29 peek.bat.del

Wed 15 Nov 06 11:12 225 peek.pl.del

Wed 15 Nov 06 12:13 28 pop.bat.del

Wed 15 Nov 06 12:13 32 push.bat.del

4 File(s) 314 bytes

0 Dir(s) 3,808,210,944 bytes free

Now, let’s say that I’ve decided to archive them instead of deleting them, so I move them to another directory. I don’t want to keep the .del extension, but I don’t want to rename each file by hand (either in Windows Explorer, or from the command line).

I know that I can rename each file individually, e.g.,

rename peek.bat.del peek.bat

But simply making use of wildcards doesn’t work at all. For instance

rename *.bat.del *.bat

just leaves me with files with names like peek.bat.bat. Not what I’m looking for at all.

It’s possible to use the DOS “for” command to handle this, as long as you make use of tokens. For instance, I can’t just say something like

for %i in (*.*.del) do rename *.*.del *.*

It just doesn’t work.

After some web-searching, and general messing around, I can now do it with the following command (all on one line please):

for /f “tokens=1,2 delims=.” %i in (’dir *.*.del /b’) do rename %i.%j.del %i.%j

And it’s really that easy! Here’s what the various bits of the command are:

  • for /f - We’re using the for command. The /f flag here means that we’re parsing the output of a command (the dir command that’s discussed below).
  • “tokens = 1,2 delims=.” - This breaks up each item into parts, each part deliminated by a period “.”. The 1,2 shows that I’m naming the first two tokens.
  • %i - What I’m going to call each element that I pull from the set. Actually, %i will be the first term, %j will be the second, etc.
  • in (’dir *.*.del /b’) - This defines the set that I’m pulling each element out of. I got this fu from a Yahoo Answers page, and all it does is take a bare directory listing of my current directory, showing only those files that fit the *.*.del filename pattern.
  • do rename - I’m going to be performing the rename command on each element.
  • %i.%j.del - The rename command takes two arguments; the first is the name of the file to be renamed. Here, we see that each file to be renamed has three parts, the %i part (file name), the %j part (original extension of the file, e.g., bat, pl) and the .del part (final extension that the file now has).
  • %i.%j - The second argument is what I want the renamed file to be called. Here we’re just saying that we want the file to have its file name and original extension.

Example

Here’s what it would look like in action:

F:\ToDo\archive>for /f “tokens=1,2 delims=.” %i in (’dir *.*.del /b’) do rename %i.%j.del %i.%j

F:\ToDo\archive>rename peek.bat.del peek.bat

F:\ToDo\archive>rename peek.pl.del peek.pl

F:\ToDo\archive>rename pop.bat.del pop.bat

F:\ToDo\archive>rename push.bat.del push.bat

Note: I typed the first line, DOS took care of the rest. And here’s what I see in my directory now:

Wed 15 Nov 06 12:13 29 peek.bat

Wed 15 Nov 06 11:12 225 peek.pl

Wed 15 Nov 06 12:13 28 pop.bat

Wed 15 Nov 06 12:13 32 push.bat

Sources

  • Impetus to try figuring out the FOR command, as I’ve never really gotten into it: LifeHacker post.
  • Help on FOR command: “help for” at command prompt
  • Help on setting up tokens and dir command to deal with file names: Yahoo answers page.
2 Comments »

There’s a nice post over on LifeHacker that talks about SlickRun - like it took them soooo long to figure out how cool it was! Anyway, one of the comments refers to app.bat, a batch file that will let you append text to any file. Turns out that I wrote that batch file, but forgot about it. I was pleasantly reminded when someone commented on one of my old posts about Slickrun. Then, when I checked out the LifeHacker post again, I see that my legions of fans have come to my rescue already! Thanks Jimmer and/or Jim, and to Blog Jones for correcting himself/herself. :) :) :)

And for anyone who wants to see the original post on the app.bat file, check it out here.