3

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.

slhck
  • 223,558
  • 70
  • 607
  • 592
Morton
  • 31
  • 1
  • 1
  • 3
  • 4
    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 09 '13 at 06: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 09 '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 09 '13 at 17:17

5 Answers5

6

How about this:

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

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.

slhck
  • 223,558
  • 70
  • 607
  • 592
ForeverWintr
  • 879
  • 5
  • 14
  • 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 09 '13 at 07: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 09 '13 at 08:05
  • 7
    Don't do this ([Why you shouldn't parse the output of ls(1)](http://mywiki.wooledge.org/ParsingLs))! – Adrian Frühwirth Apr 09 '13 at 16:52
5

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(".")]'
Cristian Ciupitu
  • 5,513
  • 2
  • 37
  • 47
2

Use this code

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

Apparently \r matches ? in sed.

zx485
  • 2,170
  • 11
  • 17
  • 24
E_v2.0
  • 21
  • 1
1

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
0-_-0
  • 259
  • 2
  • 5
0

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:

https://superuser.com/a/858671/365691

Adam D.
  • 101
  • 4