Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Mass filename changes using terminal? How?

Hello,

I recently put a Linksys NAS on my network. Unfortunately, the EXT3 format used on the disks does not like filenames with special characters such as "/" or "?". So I cannot copy files from my PowerBook to the NAS with these characters in their names.

A search of my hard drive shows 800+ files with these forbidden characters.

Is there a way to use terminal (or any aspect of OS X) to do a mass change of these characters to a more acceptable character (i.e. changing all instances of "/" to "-")?

Thanks for the help.

Jim

PowerBook G4 Titanium, Mac OS X (10.3.9)

Posted on Dec 7, 2006 3:52 PM

Reply
7 replies

Dec 7, 2006 8:04 PM in response to Gryff

Hi Jim,

The "/" and "?" are special characters in unix and certainly can cause trouble in filenames. The rename, which you want to do, can be done in Terminal. However, I am not spiffy enough with unix to come up with a quick solution for you. I suggest that you post this issue in the unix forum. Someone there should be able to give you a good solution.

Rich

EMAC G4 1.0 GHz Mac OS X (10.4.8)

Dec 8, 2006 5:26 AM in response to Gryff

Jim
Welcome to Apple Discussions!!
(i.e. changing all instances of "/" to "-")
As Rich advises, I would post in the Unix forum. I'm sure Gary will enjoy this 🙂

One thing to be aware of: the character '/' is actually illegal in Unix filenames and will not appear as such in the Terminal. Instead, "under the hood", Mac OS X translates a '/' to a ':', and vice-versa, since ':' is illegal in Finder.

A second point is that I would be loath to try this at all without an up-to-date backup. But of course, you have that, don't you?

Dec 8, 2006 7:54 AM in response to Michael Conniff

Jim

I couldn't resist trying this out. As a starting point, you could ask Gary what he thinks of it, which will do what you want. But it is a bit hairy!

Note, you should copy and paste the following into the Terminal window, one line at a time, with a return after each line. After the first and second lines, the shell will respond with a secondary prompt '>' to show the command is not complete:

sudo find / \( -name "?" -o -name ":" \) -exec echo 'mv "{}" `echo "{}" |
sed "s^\?^_^g
s^:^-^g" ` ' \; | sh

This will replace all '?'s with '_'s and all ':'s ('/'s in Finder) with '-'s. I tried it in a test directory: the command above will search (and replace) on your entire boot volume. If you want to try it in a test directory, replace the first '/' in the command with the full path to the directory, e.g. "~/testdir" (where '~' means your home directory.

Dec 8, 2006 10:41 AM in response to Michael Conniff

Hi Jim, Michael,
I apologize for missing this but we've been in crisis mode at work for a bit. Thanks Michael for e-mailing me. There's only one issue with the command that I see. The find command should be made to perform a depth-first search because as it is, it could change the name of a directory before change its contents. That could result in a "file or directory not found" error, in which case the contents wouldn't be changed.

I wrote my version all on one line. I don't know which is better but I figure that it can't hurt to have an option. The only important change is in the first line so you could simply add the "-d" option to the find command. You could add that to Michael's command and it should work.

sudo find -d / \( -name " ?" -o -name " :" \) -exec echo 'mv "{}" "$( echo "{}" | sed -e "s^\?^_^g" -e "s^:^-^g" )"' \; | sudo sh

I've made a few other minor changes that are simply a matter of taste. It's been my experience that the output of command substitution generally doesn't require quoting but it's a habit.

Edit: I forgot that the shell at the end of the pipe will not be run with root privileges just because the find command is. Thus, I added a second sudo. However, you shouldn't have to authenticate again unless the whole thing takes more than five minutes. Even in that case, entering your password again shouldn't interfere with the process.
--
Gary
~~~~
Someone did a study of the three most-often-heard phrases in New York City. One is "Hey, taxi." Two is, "What train do I take to get to Bloomingdale's?" And three is, "Don't worry. It's just a flesh wound."
-- David Letterman

Dec 8, 2006 10:46 AM in response to Gary Kerbaugh

Gary

Thanks for taking a look! You're right—I should have remembered since I needed the depth first option just a couple of days ago!
I wrote my version all on one line.
I wondered if you would 🙂

As it happens, it doesn't matter (except for the "-e" for sed) while you're within the single quotes—plus if you remember the pipe symbol at the end of your first line would imply the command continues, even if it weren't within the quotes.

Jim
Note what Gary said about the "-d" option. My version would fail if you had a directory with '?' or '/' in the name.

Also, if you are going to do this, please be patient, that command will take a while 🙂

Dec 8, 2006 5:08 PM in response to Gary Kerbaugh

Thanks to everyone for the responses. Unfortunately, none seem to work. Could be a User Headspace Error on my part, but here is what I have done.

Per Gary's suggestion, I tried entering the following into Terminal:

sudo find -d ~/Documents \( -name " ?" -o -name " :" \) -exec echo 'mv "{}" "$( echo "{}" | sed -e "s^\?^_^g" -e "s^:^-^g" )"' \; |

(I want to change all the files in my Documents directory - including files within multiple nested sub-directories - nested directly within my home directory)

Terminal returned the following:

tcsh: Invalid null command.

When I entered "sudo sh", it asked for my password, then changed my prompt to:

sh-2.05b#

If I entered Gary's original command string at this prompt, it returned a > prompt with nothing else on the line.

--------

Per Michael's suggestion, I tried entering the following into Terminal:

sudo find ~/Documents \( -name " ?" -o -name " :" \) -exec echo 'mv "{}" `echo "{}" |
sed "s^\?^_^g
s^:^-^g" ` ' \; | sh

It returned the following several dozen times:

usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory


but no files names were changed.

Pleae note that I am Unix illiterate, so I will be entering your suggested commands relatively literally.

Thanks again,

Jim



PowerBook G4 Titanium Mac OS X (10.3.9)

Dec 9, 2006 8:36 AM in response to Gryff

Jim
tcsh: Invalid null command
Ah, you're using tcsh. Bad news! I'm sure it could be made to work, but I've switched to bash because it is better for this sort of stuff. Gary will tell you to switch to zsh, but for now bash will do. I just tried the command as posted and tcsh complained loudly!

First point: often when you try to copy/paste from a browser window, you get an extra space appended to the line. It often doesn't matter, but it could here (may explain the "tcsh: Invalid null command" message). So copy the commands into a TextEdit document, which you have changed to Plain Text from the Format menu. Then be sure not to include any trailing space.

Second point, we'll scrap the use of sudo since it is only your Home directory that you are interested in.

Third point: as I said, we'll use bash. The prompt will change to a '$' instead of a '%'. When you've finished, you can return to tcsh with a plain exit command.

So, copy and paste the following into the Terminal window, one line at a time, with a return after each line:
<pre>

bash
find -d ~/Documents \( -name "?" -o -name ":" \) -exec echo 'mv "{}" `echo "{}" |
sed -e "s^\?^_^g" -e "s^:^-^g" ` ' \; | sh

</pre>This should work—it did for me!

Note:
it returned a > prompt with nothing else on the line.
It will do this after the second line above—it is an invitation to complete the command 🙂

Mass filename changes using terminal? How?

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.