Results 1 to 5 of 5
I have th following bash script ( sfvsort ) that checks sfv files and moves directories if everything is ok:
Code:
# /bin/bash
startingdir=$PWD
if [ -d sfv_ok ] ; ...
- 07-02-2008 #1
Bash newbie needs your help with spaces in dir names
I have th following bash script (sfvsort) that checks sfv files and moves directories if everything is ok:
When there are spaces in directory names it does not work:Code:# /bin/bash startingdir=$PWD if [ -d sfv_ok ] ; then echo 'sfv_ok exists.' else mkdir sfv_ok echo 'Made directory sfv_ok.' fi find $PWD -iname "*.sfv" | \ while read I; do cd "$(dirname "$I")" cfv -i -f "$I" -q testresult=$? if [ $testresult = 0 ]; then echo Command to issue: mv \"$(dirname "$I")\" \"$startingdir/sfv_ok/$(basename "$(dirname "$I")")\" mv \"$(dirname "$I")\" \"$startingdir/sfv_ok/$(basename "$(dirname "$I")")\" fi done
I'm puzzled for several reasons:Code:daan@schmauck:~/dance$ ls Eskimo - Break Rules (2004) daan@schmauck:~/dance$ sfvsort Made directory sfv_ok. /home/daan/dance/Eskimo - Break Rules (2004)/00-eskimo-break_rules-cdr-2004-bmi.sfv: 1 files, 1 OK. 0.431 seconds, 28972.6K/s Command to issue: mv "/home/daan/dance/Eskimo - Break Rules (2004)" "/home/daan/dance/sfv_ok/Eskimo - Break Rules (2004)" mv: target `(2004)"' is not a directory daan@schmauck:~/dance$ mv "/home/daan/dance/Eskimo - Break Rules (2004)" "/home/daan/dance/sfv_ok/Eskimo - Break Rules (2004)" daan@schmauck:~/dance$ ls sfv_ok/ Eskimo - Break Rules (2004)
1) Why doesn't it work? I've got the quotes.
2) Why does it complain only after the fourth space and not after the second?
3) Why does the mv command work when I copy paste it to the command line?
How do I do it right?OS's I use: Debian testing, Debian stable, Ubuntu, Windows XP, Windows Vista
- 07-03-2008 #2
1. I have no idea why it doesn't work.
2. Once again, can't help you
3. My best guess is that "dirname" and "basename" aren't behaving consistently. When I tried to use them, I got quite a few weird results.
How do you do it right? Well, okay, I tried this
I'm not sure if this is satisfactory, however. Because, I'm not sure what you were planning with the cd command ( why would you cd to the cwd? ), or whether you're going to continue to execute from the cwd.Code:#!/bin/bash startingdir=$PWD if [ -d sfv_ok ] ; then echo 'sfv_ok exists.' else mkdir sfv_ok echo 'Made directory sfv_ok.' fi find ./ -iname "*.sfv" | \ while read I; do #cd "$(dirname "$I")" What is this for? echo cfv -i -f "$I" -q testresult=$? if [ $testresult = 0 ]; then echo Command to issue: mv "$PWD/$(echo "$I" | sed "s/\.\///g")" "$startingdir/sfv_ok/$(echo "$I" | sed "s/\.\///g")" mv "$PWD/$(echo "$I" | sed "s/\.\///g")" "$startingdir/sfv_ok/$(echo "$I" | sed "s/\.\///g")" fi done
So, basically what this does, it uses $PWD to print the parent working dir instead of dirname and basename ( they seemed to be really inconsistent ), and uses find to search "./" instead of $PWD to avoid applying the full file name to $I. We can then use sed to cut off the "./" part that is attached on by "find" to print the filename and $PWD.
An even simpler solution.
This simply uses "./" instead of including the full filename.Code:#!/bin/bash startingdir=$PWD if [ -d sfv_ok ] ; then echo 'sfv_ok exists.' else mkdir sfv_ok echo 'Made directory sfv_ok.' fi find ./ -iname "*.sfv" | \ while read I; do #cd "$(dirname "$I")" What is this for? echo cfv -i -f "$I" -q testresult=$? if [ $testresult = 0 ]; then echo Command to issue: mv "$I" "./sfv_ok/$(echo "$I" | sed "s/\.\///g")" mv "$I" "./sfv_ok/$(echo "$I" | sed "s/\.\///g")" fi done
Anyway, unfortunately I can't figure out why it wouldn't be working, or why it was working the way you had it.
By the way, all of my testing wad done on a file named "The test From (200
.sfv" to make circumstances similar to what you're dealing with.
- 07-03-2008 #3
So the problem, at a glance, is with your escaping of quotes. In Bash, we quote so as to group arguments. When you escape them, you are saying "this is actually a quote". For instance:
In this example, mv sees its first argument as my file, and its second as new_dir.Code:mv "my file" new_dir
In this example, mv sees its first argument as "my, its second as file", and its third as new_dir.Code:mv \"my file\" new_dir
In this line:
the escaped quotes are correct, as we want them to appear in echo's output. In this line:Code:echo Command to issue: mv \"$(dirname "$I")\" \"$startingdir/sfv_ok/$(basename "$(dirname "$I")")\"
The quotes should not be escaped, because we are actually using them to group arguments. Try this line instead:Code:mv \"$(dirname "$I")\" \"$startingdir/sfv_ok/$(basename "$(dirname "$I")")\"
Hopefully, this answers questions 1).Code:mv "$(dirname "$I")" "$startingdir/sfv_ok/$(basename "$(dirname "$I")")"
Question 3) is also easy: note that when you copied the line to run the mv command yourself, you did not escape the quotes. This is correct, and this is why the command worked.
As for Question 2), this is actually due to the way that mv works. When you run this command:
mv has a lot of arguments. They are:Code:mv \"/home/daan/dance/Eskimo - Break Rules (2004)\" \"/home/daan/dance/sfv_ok/Eskimo - Break Rules (2004)\"
Without looking at the implementation, I can't say for certain, but I bet that the first thing that mv does is check that the destination (the last argument, in this case (2004)") is a valid directory. Because in this case, it obviously isn't, it throws an error before checking any of the other arguments.Code:"/home/daan/dance/Eskimo - Break Rules (2004)" "/home/daan/dance/sfv_ok/Eskimo - Break Rules (2004)"
I hope that this makes sense!DISTRO=Arch
Registered Linux User #388732
- 07-03-2008 #4
Thank you, SagaciousKJB and Cabhan! It's absolutely great that you've taken some time to look at my midnight hackings.
Here's what your proposed corrections do:
So Cabhan's improvement is correct. I'm not sure why I left the \ escapes, it makes a lot more sense like this.Code:daan@schmauck:~/dance$ ls Eskimo - Break Rules 2004 daan@schmauck:~/dance$ sfvsortkjb1 Made directory sfv_ok. cfv -i -f ./Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv -q Command to issue: mv /home/daan/dance/Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv /home/daan/dance/sfv_ok/Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv mv: cannot move `/home/daan/dance/Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv' to `/home/daan/dance/sfv_ok/Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv': No such file or directory daan@schmauck:~/dance$ sfvsortkjb2 sfv_ok exists. cfv -i -f ./Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv -q Command to issue: mv ./Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv ./sfv_ok/Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv mv: cannot move `./Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv' to `./sfv_ok/Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv': No such file or directory daan@schmauck:~/dance$ sfvsortcab sfv_ok exists. /home/daan/dance/Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv: 1 files, 1 OK. 0.022 seconds, 559279.8K/s Command to issue: mv "/home/daan/dance/Eskimo - Break Rules 2004" "/home/daan/dance/sfv_ok/Eskimo - Break Rules 2004" daan@schmauck:~/dance$ ls sfv_ok/ Eskimo - Break Rules 2004 daan@schmauck:~/dance$
Why I cd into dirname before issuing the cfv command: here's what happens if I remove echo in line 13 in KJB's second script to activate the cfv command:
For some reason the name of mp3 to be checked is given without any indication of where it should be found:Code:daan@schmauck:~/dance$ sfvsortkjb2.2 Made directory sfv_ok. 01-eskimo_-break_rules-bmi.mp3 : No such file or directory ./Eskimo - Break Rules 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv: 1 files, 0 OK, 1 not found. 0.000 seconds, 0.0K/s daan@schmauck:~/dance$
Thanks a million, guys!Code:daan@schmauck:~/dance$ cat Eskimo\ -\ Break\ Rules\ 2004/00-eskimo-break_rules-cdr-2004-bmi.sfv | grep mp3 01-eskimo_-break_rules-bmi.mp3 30b22448 daan@schmauck:~/dance$
OS's I use: Debian testing, Debian stable, Ubuntu, Windows XP, Windows Vista
- 07-05-2008 #5Linux Engineer
- Join Date
- Feb 2005
- Posts
- 1,044
As a general rule it's A Bad Idea (as you've already found out!) to put spaces in filenames since they're separators in proper operating systems. However, it has given you a valuable lesson in the proper use of quoting!


Reply With Quote