Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

onmyoji

macrumors newbie
Original poster
Jan 8, 2016
7
0
Hello all. I've never used Automator before, but someone directed me towards it. As part of my job, I need to take a bunch of files that are sequentially numbered (ex: 0000.txt, 0001.txt, 0002.txt, 0003.txt, etc.) and need to rename them with a very different sequence. The sequence I need is nearly always:

000-001.txt
002-003.txt
004-005.txt
006-007.txt
008-009.txt
010-011.txt, etc.

I would like the renaming to initiate with 000-001, going up until it runs out of files. Even if it makes it as far as 998-999. Right now, I don't think Automator can do this, but if it can, I'd love to learn how. I've literally changed hundreds of thousands (probably millions by now) of filenames manually and could use a break.

If anyone has an easy solution that does not use Automator, that's fine too. But I have zero experience running scripts, etc., so if it involves any of that, I might need basic help learning how to run them.

Thanks so much in advance!

-- O

P.S. -- It's my very first time posting here. My apologies if I missed something or otherwise did something wrong.
 
Python is probably a better tool for this.

Open up your file editor of choice (or get Sublime Text if you don't have a file editor of choice already).

Code:
from os import listdir, rename

# This will loop over all the filenames in the current directory:
for filename in listdir('.'):
    # This will cut off the .txt from the end then convert from a string to a number.
    oldNumber = int(filename[:-4])
    # This line will generate the new filename.
    newName = '{:03}-{:03}.txt'.format(oldNumber * 2, oldNumber * 2 + 1)
    # This will rename the old file.
    rename(filename, newName)

Save this with whatever name you want. Files with Python code normally have the extension .py

Fire up terminal. cd to the directory with the files that need to be renamed. Then use the command python /full/path/to/where/you/saved/the/script.py

And you're done.

Two potential problems with the code I gave you.
#1 - Doesn't handle the possibility of files which you don't want to be renamed also being in the folder. Let me know what the criteria should be that the script should look for if that's the case.
#2 - If a file has a number of 500 or more, it'll end up using numbers with more than 3 digits in the rename. But the files with numbers under 500 will still only have 3 digits in their name... Could mess up file sorting or something. You didn't really say why you wanted the numbers padded to 3 digits.
 
Thanks! I'll give it a shot. I have zero experience with Python too, so I'll do my best.

To answer your question, I have the filenames padded to three characters because about 97% of the time, I have a directory with 100-999 files to rename. Very rarely do I have a directory with 1000 or more files. I keep the padding to three digits in the first case and four in the rare cases just so that the files are displayed properly. Should I amend your above code with that information in mind?

Will try the above code right now. Thanks!

-- O
[doublepost=1452353250][/doublepost]I got "permission denied" when attempting to run the file. I haven't changed any Terminal settings or anything that I'm aware of. Sorry I'm such a novice with all this basic OSX stuff. I just never had to learn how to do anything Terminal-related. If it makes a difference, I'm logged in to my own private computer. There's no other "administrator" account or anything that I'm aware of.
 
Here's a solution and "how to" that implements the necessary logic in a C shell script (csh or tcsh). Put the following in a file (text file) and save it as r_rename in the directory where you have files you want to rename (the # on the first line is necessary, it tells the system that this file contains a C shell script):
Code:
#
set do_it = no
#
set n = 0
foreach file ( [0-9][0-9][0-9][0-9].txt )
  @ n1 = 2 * $n
  if ( $n1 == 1000 ) then
     echo NOTE : Have run out of numbers for renaming.
     echo Quiting on file $file
     exit 1
  endif
  @ n2 = $n1 + 1
  set newFile = `echo $n1 $n2 | awk '{ printf "%3.3i-%3.3i.txt", $1,$2}'`
  echo Rename $file to $newFile
  if ( $do_it == yes) mv $file $newFile
  @ n += 1
end
if ( $do_it == yes ) then
  echo STATUS : All files renamed
else
  echo STATUS : Test run completed
endif

This script will only handle files with names that follow the pattern of four digits with the extension ".txt" and will stop with a complaint if there are more than 500 files to rename. The do_it variable controls running the script in a test mode. If set to "no" (as it is shown here) the script will just step through the files and list the changes it would make if run in non-test mode (no filenames are changed). If set to "yes" it will rename the files. I recommend running it in test mode first.

Note the use of both "forward" and "reverse" apostrophes on the "set newline = " line. These have to be correct in order for the script to work.

Open up the Terminal app and use the following series of commands to run the script (don't bother entering the lines that start with a # this time as those are just comments describing what's going on):

Code:
#
#  Move to the directory where the files are.  Here it's
#  assumed to be in /User/username/workDirectory.
#
cd workDirectory
#   
#  Enable the C shell scripting environment.
#   
csh
#
#  Make the script "runnable" by OS X.  You only need to do
#  this one time.
#
chmod 777 r_rename
#
#  Run the script and check for normal termination.
#
r_rename
if ($status != 0) then
  echo NOTE : Problem encountered in script r_rename
endif
#
#  Go back to your original environment.
#
exit

This series of commands puts you into the C shell environment (the csh command) and takes you back out into whatever environment you started with at the end (the exit command).
 
I got "permission denied" when attempting to run the file. I haven't changed any Terminal settings or anything that I'm aware of. Sorry I'm such a novice with all this basic OSX stuff. I just never had to learn how to do anything Terminal-related. If it makes a difference, I'm logged in to my own private computer. There's no other "administrator" account or anything that I'm aware of.

Weird.

Stick

Code:
print('Running')

To the front of the Python code file. Try it again. Does the word Running print out? If so, it seems the files it's trying to rename somehow have a permission issue. Are you trying to rename system files or something? If not, the permission issue is with your Python script. If it's with the Python script, try running

Code:
chmod 777 /path/to/your/python/script.py

That'll give it full permissions, just in case it was missing any...
 
To be honest, Automator would have been a much simpler way of doing it all through a nice GUI ;-)

There are extremely few things I have ever managed to accomplish through Automator, and everything I've ever managed to do took quite a while to set up and would have been much easier in Python.
 
Hey guys! Sorry I haven't been around the last couple of days. Got very busy. Anyway, I plan to try the new suggestions soon.

Was just going to say to Crazy Badger that I tried using Automator, but it doesn't seem to do exactly what I want it to do. If it even had an option to use only odd or only even numbers, I could probably get what I'm looking for if I run my files through 2-3 Automator cycles. But it doesn't seem to do that. Trust me, I'd LOVE a situation with an actual GUI as I have zero experience with Python and C scripts. Aside from this thread anyway.

Hope to test things soon. I'll let you guys know how it goes.

-- O
 
I do not think it would work for this case, but it is worth mentioning:

If you select multiple files in Finder and right-click or control-click, one of the choices is 'Rename n items'. That puts you into a GUI which has options to replace text, add text, reformat, and renumber file names.

A.
 
OK. After doing chmod 777, I get different errors:

from: can't read /var/mail/os
/full/path/script.py: line 3: syntax error near unexpected token `('
/full/path/script.py: line 3: `for filename in listdir('.'):'

The script is the original one. I didn't modify it to print 'running' because I'm not renaming system files or anything that should have different permissions.
 
OK. After doing chmod 777, I get different errors:

from: can't read /var/mail/os
/full/path/script.py: line 3: syntax error near unexpected token `('
/full/path/script.py: line 3: `for filename in listdir('.'):'

The script is the original one. I didn't modify it to print 'running' because I'm not renaming system files or anything that should have different permissions.

Try "python script.py" where script.py is the file you have saved the script to. From the errors above you are trying to run the python script through a shell rather than python.
 
  • Like
Reactions: ArtOfWarfare
If this is the type of thing you might end up doing regularly, you might consider looking into Noodlesoft's Hazel 3.0... seem to recall it could get pretty detailed regarding naming regimes on files...

Again, if you manage to get what you need from the kind souls and their scripting knowledge, perfect! But if this is something that might happen regularly, maybe consider the above?
 
@cqexbesd - When I do that, I get "No such file or directory." It thinks the "python" part you're adding before "script.py" (the file name) is part of the directory.

@Cassady - I do this exact renaming scheme very frequently. I will look into it. Thanks!
[doublepost=1452621665][/doublepost]@cqexbesd If I move the script into the same folder as the files I want to replace and then type "python script.py" in the Terminal, I get different errors:


Traceback (most recent call last):
File "script.py", line 7, in <module>
newName = '{:03}-{:03}.txt'.format(oldNumber * 2, oldNumber * 2 + 1)
ValueError: zero length field name in format
 
Just before the "newName = " line in your python script put in the following:

print filename, oldNumber

with the same indentation. This will print out some diagnostic information that might sort out your problem.
 
@cqexbesd - When I do that, I get "No such file or directory." It thinks the "python" part you're adding before "script.py" (the file name) is part of the directory.

I'm not sure exactly what you have typed or what output you are getting so its hard to say what is wrong.

If you type python on its own you should get a prompt that looks like ">>>". If you do then press ctrl-D to exit and we know the "no such file or directory" wasn't from the shell looking for python. That would just leave the path to script.py being wrong. I don't know where you have stored it but you can always drag it from a finder window into the terminal and it's full path will be filled in.


@cqexbesd If I move the script into the same folder as the files I want to replace and then type "python script.py" in the Terminal, I get different errors:


Traceback (most recent call last):
File "script.py", line 7, in <module>
newName = '{:03}-{:03}.txt'.format(oldNumber * 2, oldNumber * 2 + 1)
ValueError: zero length field name in format

From a 10 second look at the script it tries to process everything in the directory. It probably sees itself with an unexpected file name and fails. Try putting the script somewhere that isn't the directory you are trying to process.
 
OK. I think I must have done something wrong when trying to run the command back when the python script was first contributed. I tried it again just now and got a different error. So to be specific,
(1) I chmod 777-ed the directory I'm trying to change.
(2) I cd-ed to the directory I wanted to change.
(3) Then I ran the command "python path/script.py."

I get the following error:
Traceback (most recent call last):
File "/path/script.py", line 7, in <module>
newName = '{:03}-{:03}.txt'.format(oldNumber * 2, oldNumber * 2 + 1)
ValueError: zero length field name in format

Hopefully this will be more helpful. Thanks so much for your patience.

- O
[doublepost=1452983521][/doublepost]P.S. -- I think the earlier "No such file or directory." was an error in the syntax I was using. Probably not the code.
 
OK. I think I must have done something wrong when trying to run the command back when the python script was first contributed. I tried it again just now and got a different error. So to be specific,
(1) I chmod 777-ed the directory I'm trying to change.
(2) I cd-ed to the directory I wanted to change.
(3) Then I ran the command "python path/script.py."

I get the following error:
Traceback (most recent call last):
File "/path/script.py", line 7, in <module>
newName = '{:03}-{:03}.txt'.format(oldNumber * 2, oldNumber * 2 + 1)
ValueError: zero length field name in format

Hopefully this will be more helpful. Thanks so much for your patience.

- O
[doublepost=1452983521][/doublepost]P.S. -- I think the earlier "No such file or directory." was an error in the syntax I was using. Probably not the code.

Hi, the ValueError is because I was trying to take advantage of features available in Python 2.7 but not 2.6. Out of curiosity, what version of OS X are you using? Seems like it's been coming with 2.7 pre installed for several years now.

Anyways, to make it work with 2.6, change the offending line to:
Code:
    newName = '{0:03}-{1:03}.txt'.format(oldNumber * 2, oldNumber * 2 + 1)

Note that I added a 0 and a 1 to the code. Stuff surrounded in {} means you're going to replace them with something, which will be given inside of format(). The :03 meant that the something should be padded to 3 digits using 0s. In 2.7, that is all that's needed. In 2.6, it needs you to specify which something you want to replace in each {}. So the new 0 and 1 mean you want the first and second somethings, respectively.
 
Out of curiosity, what version of OS X are you using? Seems like it's been coming with 2.7 pre installed for several years now.

I should've perhaps mentioned I'm using a laptop that's pretty old (2008?), and it's running OSX 10.6.8. No clue how to check what version of Python I have. Should I just change the code as you suggested, or is it possible I have an even more ancient version of Python that needs additional workarounds?

Sorry for all the newbie errors guys. Thanks for being patient with me.

-- O
[doublepost=1453051757][/doublepost]OOOOH! It works now! Thanks so much everyone!

If I might be permitted to ask one more question, I'd like to make one adjustment. I noticed that if my original set of files starts mid-way through the sequence (say with 0005.txt), the code would turn that file into 010-011.jpg. However, I'd still like it to change the first file (whatever it is named) to "000.001.txt." Is there a way to adjust the code to allow for that?

If it's easier, all of the files I need to rename are always located in their own separate directory, and thus the script does not need to be able to differentiate between files it's supposed to rename and files it isn't. If it's easier to write the script so that files of ANY name will be renamed this way, then feel free to do that.

Thanks SOOOO much everyone. This will save lots of time.

-- O
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.