JeroenM Posted January 2, 2004 Report Share Posted January 2, 2004 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 More sharing options...
fuzzylizard Posted January 2, 2004 Report Share Posted January 2, 2004 No sure how to place it into a script, but renaming the files is simple $ mv photo\ 001.jpg photo001.jpg The trick is that you need to escape the space. You do this by placing a backslash '\' before the space. Link to comment Share on other sites More sharing options...
JeroenM Posted January 2, 2004 Author Report Share Posted January 2, 2004 thanks. seems I have to use mv instead of rename. after searching for yet another while I found this post http://dbforums.com/arch/144/2003/10/941250 I think this will solve (part of) my problem. Once I figure it out that is. Link to comment Share on other sites More sharing options...
aru Posted January 3, 2004 Report Share Posted January 3, 2004 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 More sharing options...
bvc Posted January 3, 2004 Report Share Posted January 3, 2004 superaru strikes again! we've missed ya. Hope all is well! Link to comment Share on other sites More sharing options...
Guest anon Posted January 3, 2004 Report Share Posted January 3, 2004 absolutely brilliant. B) Link to comment Share on other sites More sharing options...
Steve Scrimpshire Posted January 3, 2004 Report Share Posted January 3, 2004 (edited) 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 January 3, 2004 by Steve Scrimpshire Link to comment Share on other sites More sharing options...
aru Posted January 4, 2004 Report Share Posted January 4, 2004 (edited) 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 January 4, 2004 by aru Link to comment Share on other sites More sharing options...
JeroenM Posted January 15, 2004 Author Report Share Posted January 15, 2004 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 More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now