Jump to content

renaming files with space in name


Recommended Posts

Hi,

 

I've got directories with images and they are called like this:

  • photo 001.jpg
  • photo 002.jpg

the problem lies in the spaces in the names.

 

Does anyone know how I can rename them so the space in the name gets dumped?

Or how I can fit that problem into this piece of pretty script:

#!/bin/sh

#
# $Id: iRename,v 1.1 2001/11/20 03:11:28 vijoy Exp vijoy $
#

# Cleanup and create input
inputfile=`ls *.jpg *.JPG`
# aanpassing vanwege domme spaties in namen
# helaas werkt ze nog niet
# inputfile=`ls *`

for imgname in $inputfile
do
   if [ ! -f $imgname ]; then
       echo $imgname" not found."
       break
   fi

   # Extracting image information
   info=`head $imgname| strings| grep 200 | grep :`
   newname=`echo $info|cut -d ' ' -f 1`"++"`echo $info|cut -d ' ' -f 2`
   newname=`echo $newname|sed s/:/-/g`

# Uncomment for lost time-date information
# newname=2001-11-04++00-00-`echo $imgname|cut -d '.' -f 1|cut -d '0' -f 2-`

   # Rename only if valid newname
   if [ "X$newname" != "X++" ]; then
       mv -i $imgname $newname
   fi
done

rm -rf .input

Link to comment
Share on other sites

This is what I do when I have to do such thing:

 

~$ find . -name "* *" -exec sh -c 'mv ${0} ${0// /_}' {} \;

 

Find will search for files containing at least a blank space on their names in the working directory and it's descendants. Then, when matching a file it will call /bin/sh to execute 'mv'; the parameter is passed to the shell through '{}' (which equals to the file matched by find, see "man find"); the shell will see it as '$0'; then by parameter substitution it will change all seen ' ' with '_' so the command 'mv' will perform:

 

mv "./path/to/some file with spaces" "./path/to/some_file_with_spaces"

 

HTH

Link to comment
Share on other sites

aru: I don't want to hijack this thread, but it looks like the problem is solved anyway. I have a question about the command above. I uderstand everything except this at the end:

{}

Why is that there? Isn't the ${0} how the filename found is passed to the command?

 

And shouldn't this:

${0// /_}

be

${0/\ /_}

 

?

Edited by Steve Scrimpshire
Link to comment
Share on other sites

Thank you guys :P It's only that I don't have enough free time to have fun with you and linux :( :(

 

aru: I don't want to hijack this thread, but it looks like the problem is solved anyway. I have a question about the command above. I uderstand everything except this at the end:

{}

Why is that there? Isn't the ${0} how the filename found is passed to the command?

 

And shouldn't this:

${0// /_}

be

${0/\ /_}

 

?

Clever questions my friend, I'll will quote some parts of man pages in order to explain you why is that:

 

The '{}' stands for the filename matched passed as an argument to the command executed through '-exec'; as shown in 'man find':

   ACTIONS
      -exec command;
             Execute command; true if 0 status is returned.  All following arguments to find are taken to be arguments to  the  command until an argument consisting of `;' is encountered.  The string `{}' is replaced by the current file name  being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as  in some versions of find.  Both of these constructions might need to be escaped (with a `\') or quoted to protect  them from expansion by the shell.  The command is executed in the starting directory.

 

For the second question, it is true that normally $0 is the proccess name (in a shell is 'bash' and in a script is it's the name of the script) but when you call bash or sh with '-c' then the behavior changes a little bit as shown here in 'man bash':

 

OPTIONS
      In  addition to the single-character shell options documented in the description of the set builtin command, bash interprets the following options when it is invoked:
      -c string If the -c option is present, then commands are read from string.  If there are  arguments  after  the  string, they are assigned to the positional parameters, starting with $0.

 

Normally I add two {} {} at the end of my find execs to keep coherence with normal bash behavior, but in order to make it simplier to understand I put just one. For example, here at home I do things like this (see the two {} {} at the end of -exec, and how the parameter used is $1 instead of $0):

 

find . -type f -regex ".*\ .*" -exec bash -c 'mv "$1" "${1// /_}"' '{}' '{}'  \;

 

Finally for the last question, you don't need to scape the blank space from the shell expansion since the full command is within single quotes. The double '//' stands for match every occurrence of the pattern vs a single '/' which means match only the first. As said in 'man bash':

       ${parameter/pattern/string}
      ${parameter//pattern/string}
             The pattern is expanded to produce a pattern just as in  pathname  expansion.   Parameter  is  expanded  and  the  longest  match  of pattern against its value is replaced with string.  In the first form, only the first match is  replaced.  The second form causes all matches of pattern to be replaced with string.  If pattern begins  with  #,  it  must  match  at the beginning of the expanded value of parameter.  If pattern begins with %, it must match at  the end of the expanded value of parameter.  If string is null, matches of pattern are deleted and the /  following  pattern  may  be  omitted.  If parameter is @ or *, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list.  If parameter is an array variable subscripted with @  or  *, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list.

 

HTH and very happy to be back (at least today sunday)

Edited by aru
Link to comment
Share on other sites

  • 2 weeks later...
This is what I do when I have to do such thing:

 

~$ find . -name "* *" -exec sh -c 'mv ${0} ${0// /_}' {} \;

no, it's not ;-)

 

this is what you do:

find . -name "* *" -exec sh -c 'mv "${0}" "${0// /_}"' {} \;

 

HTH and thanks for the help.

 

this one is solved!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...