Question

In the process of posting this question I've been experimenting with my code, I've come up with something that works, but my restless intellect wants to be a better programmer, not just solve the problem at hand, so I'm posting Script 1.0 and Script 1.1 to ask the community, Why does the change to line 3 make it work?

I'm copying files from a server and renaming them. The copying is going fine; the renaming isn't. These filenames have spaces. cp handles them competently; mv seems throws an error. I expected putting "" around the variable name to resolve the issue, but it still gives an error: mv: rename /src/foo.wav to zzz - /dest/foo.wav - copied 201403261800.wav: No such file or directory. I'm trying to prepend "zzz" to the filename, but it's getting prepended to the destination path. Here's Script 1.0:

cd /src/
DATE=$(date +"%Y%m%d%H%M")
find . -type f -iname "*.wav" | while read file ; do
    if [[ "$file" != *zzz* ]]; then
        echo "Tranferring...";
        cp "$file" /dest/
        mv "$file" \zzz\ \-\ "$file"\ \-\ copied\ $DATE.wav
        echo "Transfer complete.";
    fi
done 

(The if condition ensures that I don't re-copy anything I've previously copied and renamed.)

Changing the 3rd line makes it work. But why? Here's Script 1.1:

cd /src/
DATE=$(date +"%Y%m%d%H%M")
find *.* -iname "*.wav" | while read file ; do
    if [[ "$file" != *zzz* ]]; then
        echo "Tranferring...";
        cp "$file" /dest/
        mv "$file" \zzz\ \-\ "$file"\ \-\ copied\ $DATE.wav
        echo "Transfer complete.";
    fi
done 
Was it helpful?

Solution

If you look at the output of the different find commands you'll see that find . -type f will return lines like this: ./passwd. Now you can't use that as the target, as renaming ./passwd to zzz - ./passwd would try to move it to a zzz - . folder as passwd.

By the way, you can surround the whole target name with quotes, to make it look better (also you should not escape the first z anyway):

mv "$file" "zzz - $file - copied $DATE.wav"

Also you probably want to get rid of the .wav part in the middle of the file:

mv "$file" "zzz - ${file%.wav} - copied $DATE.wav"

The ${var%string} returns the value of $var with string removed from the end of it if present. You can find more about this looking for bash string manipulation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top