Renaming file which got a quote mark ‘ in its name

quotingrename

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?

Best Answer

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).