With rename it is possible to bulk change filenames. I managed to get rid of all + with this command and replace them with underscores:

rename 's/\+/_/g' * 

I could change normal letters like a to A with.

rename 's/a/A/g' *

but I could not rename the ?, not like this /\? and not like this /?.

Is there any way to adress the "?" in the filename? Most FTP programs fail to rename files with ? as well. Midnight Commander fails. The only way I found that works so far is:

mv ?myfile.txt myfile.txt

but this command is not flexible enough. I would prefer to bulk rename all ? in all files.

  • 3
    I can remove files with true ? without any trouble - just quote them as rm "?.txt". Are you sure it is really ? ? Maybe it is some binary character that is displayed by your shell as ? ? – mvp Apr 9 '13 at 6:24
  • 3
    Can you indicate which rename tool it is that you are using (rename --version)? There are several different rename implementations out there. – Adrian Frühwirth Apr 9 '13 at 16:54
  • Can you provide more detail on what these file names look like? e.g., are the unknown characters always at the beginning of the filename? – ForeverWintr Apr 9 '13 at 17:17

How about this:

for filename in *
    if [ "$filename" == *"?"* ] 
        mv "$filename" "$(echo $filename | tr '?' '-')" 

Or as a one liner:

for filename in *; do mv "$filename" "$(echo $filename | tr '?' '-')" ; done

However, it looks like your issue isn't that there are question marks in your filenames, but rather that your filenames contain characters that ls doesn't recognize.

  • Thanx for the fast reply. is this a bash script? I tried it as ubuntu bash and it did not change anything: #!/bin/bash for filename in $(ls | grep ?) do mv $filename $(echo $filename | tr '?' '-') done – Morton Apr 9 '13 at 7:58
  • one more thing that might be important: if I list the directory with "ls" the ? in the filenam eis displayed like this: ?%84nderung.pdf but if I use "dir" it is displayed like this : \303%84nderung.pdf I know the whole problem originates from a bad UTF-8 conversion. But maybe I have to search for "\303" instead of "?" – Morton Apr 9 '13 at 8:05
  • 7
    Don't do this (Why you shouldn't parse the output of ls(1))! – Adrian Frühwirth Apr 9 '13 at 16:52

It's ugly, but here it goes, a one liner using Python:

python -c 'import os, re; [os.rename(i, re.sub(r"\?", "-", i)) for i in os.listdir(".")]'

As for cleaning up file names, maybe this will help you:

python -c 'import os, re; [os.rename(i, unicode(i, "utf-8", "ignore")) for i in os.listdir(".")]'

Use this code

for file in ./*;
  OUT=`echo $file | sed 's/\r//g'`;
  mv $file $OUT;

Apparently \r matches ? in sed.

  • \r also matches r. – gone Sep 21 '20 at 18:11

The ? char can be tricky to match. And i did not get lucky with rename. To avoid mismatches in encoding I found it easier to deal with the output of dir.

In my case the ? then turns out to be a \303\202. We still need to escape the \ with another \\

Finally iterating over all files

for i in *; do mv $i $(echo $i | tr \\303\\202 _); done

This may be overkill but with the bash script in the link provided in this answer you can rename a filename with any characters in it including question marks, newlines, multibyte characters, spaces, dashes and any other allowable character:


Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.