9

I got a little bit of a problem. One client tasked me with the migration of sites from a really old server. Don't know how they got there, but there are files with ' in their names. Is there any way to rename the file? mv doesn't seem to do the trick.

ls shows it as 90843_O\\'ConnorPaul_GeneralManager.jpg

When I try

 mv 90843_O\\'ConnorPaul_GeneralManager.jpg 90843_O_ConnorPaul_GeneralManager.jpg

it does nothing with the > in the new line as if waiting for more input.

If I try

mv 90843_O\'ConnorPaul_GeneralManager.jpg 90843_O_ConnorPaul_GeneralManager.jpg

I get the error

mv: cannot stat '90843_O\'ConnorPaul_GeneralManager.jpg': No such file or directory

Also, is there simple way to change \' to _in all files in certain folder?

  • 1
    If you have moreutils, its vidir is a simple solution to these kinds of issues. – derobert Apr 6 '14 at 18:00
3

Bash tab completion should be able to do the right thing here if you just type mv 90843_O and press tab. Otherwise, one way to properly escape the name is:

mv "90843_O\\\\'ConnorPaul_GeneralManager.jpg" dest.jpg

The double quotes remove the need to escape the ', but the two backslash characters still need to be escaped (one extra backslash for each makes four backslashes). Another option is:

mv '90843_O\\'\'ConnorPaul_GeneralManager.jpg dest.jpg

Here putting the backslashes in single quotes removes the need to escape them, but you need to end the single quotes to add a literal '. This is escaped after the quotes end.

Note the issue here is as much to do with having backslashes in the name as the single quote. To replace the \\' sequence (since there are two backslashes in the filename in the question, both will cause problems) with an underscore for all files in a directory using a loop:

for file in *"\\\\'"*; do
  mv -i "$file" "${file//"\\\\'"/_}"
done

The -i will make mv prompt if any files will be overwritten. Using prename (rename links to this on many systems):

prename -n 's:\\\\'\'':_:g' *"\\\\'"*

Remove the -n when you are happy it is doing what you want. Note that the backslash characters should be escaped inside the perl expression here, even though there are single quotes around them (without the single quotes you would need eight backslashes since four would be removed by the shell and not be part of the perl expression).

4

You can use rename for such tasks:

➜  lab  ls                                               
1dsfa.file   6033dsfa.file                           90843_O\\'ConnorPaul_GeneralManager.jpg
56dsfa.file  90843_O\'ConnorPaul_GeneralManager.jpg
➜  lab  rename "s/\'//g" *
➜  lab  ls
1dsfa.file   6033dsfa.file                           90843_O\ConnorPaul_GeneralManager.jpg
56dsfa.file  90843_O\\ConnorPaul_GeneralManager.jpg

If you want to replace ' for _ you can also use rename:

rename "s/\'/_/g" *
-1

Grrr, @Graeme beat me to it, but I'll post anyway ...

If you quote the filename with double quotes, like mv -v "90843_O'ConnorPaul_GeneralManager.jpg" 90843_O_ConnorPaul_GeneralManager.jpg, it does the trick; using -v is optional but it'll tell what it did. I believe there's a second way too apart from escaping all the chars, -if- that even is possible. The only downside I know of this way is that the shell will process the text since it's not inside single quotes, but it doesn't manipulate it at all since it's not internal code, and the extra time it takes to process is meaningless.

Just tested, you can have char like > within a double-quoted text and it will be taken as part of the filename.

As a tip for the future, you can use ./ right before the filename if it gives problems, like files starting with a dash: mv ./-file file will rename -file to file. In case like this you can't quote nor escape the filename, as an exception.

Oddly enough, I could create the file 90843_O'ConnorPaul_GeneralManager.jpg if I escaped the single quote by \', but it wouldn't create it if it wasn't either double-quoted or escaped.

PS: Bash completion is another way, it worked around the filename issue with your file, but it won't work with "dash" files/folders: simply write a part of the name and hit Tab, it does the rest.

  • Why downvote ? I was writing before the others but I wasn't quick enough to get it posted first. – rautamiekka Apr 6 '14 at 14:51
  • Wasn't me. No clue who down voted. – Igor Yavych Apr 6 '14 at 14:59
  • This answer isn't right, it ignores the backslashes in the file name which are actually more difficult to deal with than the single quote. – Graeme Apr 6 '14 at 15:48

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.