remove certain special characters from file names

I am having an issue transferring folders to my external hard drive- I dont want to change formatting on the HD.

So there are 100's of files in the folder, and the error preventing me from copying them is coming from special characters (I dont know exactly which, but I believe its "|" and "." and Im sure there are others. I've been manually renaming/removing these, but it's a pain.

Open to suggestions, but I "guess" im looking for a way to either remove those specific characters from the file name, (would doing that cause an issue with .m4a etc?) , or replace them with an underscore if necessary. The one lead I have is perl rename, but I didnt try this yet.

rename 'y/|/_/' * like this?

thanks for any suggestions

2 Answers

Yes the (Perl-based) rename command is a good candidate for this. You can add the -n or --nono option to trial-run the replacements ex.:

 -n, --nono No action: print names of files to be renamed, but don't rename.

so for example

$ rename -n 'y/|./__/' *\|*
rename(foo|bar.baz, foo_bar_baz)
rename(foo|bar|baz, foo_bar_baz)

Note that rename will not let you destructively overwrite files if their names are not unique:

$ rename -v 'y/|./__/' *\|*
foo|bar.baz renamed as foo_bar_baz
foo|bar|baz not renamed: foo_bar_baz already exists

Note that . is not a special character in the context of filenames so I'd suggest not actually replacing that.

1

In general, mmv is great at mass-renaming tasks.

But in this particular case, I'd go a completely different route: Generate a shell script with a couple of shell commands, have a close look at it if it's really what I want, and then execute it.

Rough outline:

ls -Q >/tmp/old.txt
cp /tmp/old.txt /tmp/new.txt

ls -Q will add double quotes around each name, i.e. it will give you "foo*bar" or "foo | bar".

Then replace unwanted characters in /tmp/new.txt, either manually with an editor or with sed -i -e (or perl -p -i -e if you prefer that) or tr or tr -d. Important: do not change the order in that file, and do not delete or add any line!

In any case, have a good hard look at /tmp/new.txt to see if it's really what you want the new names to look like.

Check for duplicate names! (sort /tmp/new.txt | uniq -r) Make sure there are no duplicates and if there are, edit that line manually to get a unique name.

Then put the files together with the paste command and change each line to a mv command:

paste /tmp/old.txt /tmp/new.txt | sed -e 's/^/mv -n /' >/tmp/bulk-rename

What that paste command does is it takes one line from /tmp/old.txt and one line from /tmp/new.txt and puts them together on one single line with a blank between them. The sed part adds a mv -n to the start of each of those lines. mv -n prevents overwriting an existing file.

That file now contains a lot of lines like

mv -n "foo" "bar"
mv -n "abc" "def"

Look at the file again, and when you are positive that it's what you want, execute it with sh /tmp/bulk-rename.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like