Jump to content
EduGeek EdSec 2026 is Go! 27th Oct in Derby! Join us for a day of EdTech security focused talks, networking, and an evening social ×

Recommended Posts

Posted

Ive written a little bash script that sorts photos out of the sub folders and puts them all into the root folder, but my script doesnt seem to like folders with spaces. I think its the for loop, thinking the space means its a new item and it treats "Summer 2009" as Summer and 2009.

 

Anyone point me in the right direction to sort this?

 

 

cd /Photos/new

#Move JPG files

for directory in $(find . -type d)
do (cd $directory
for file in *.jpg

do mv $file /Photos/new
echo "Moved $file "
done)

done

#Remove empty directorys
find . -type d -exec rmdir {} \;

Posted

you need to escape them like so

mkdir new\ folder

This creates a directory called "new folder"

Note the \ is right after word "new"

 

so to cd into "Summer 2009"

 

cd Summer\ 2009

Posted

try:

 

chaning $directory on line 6 to

${directory/ /\\ }

 

that should subsitute all the spaces in $directory to "\ "

 

you will have to do it for file name aswell because "random picture.jpg" will be treated as "random" and "picture.jpg"

Posted
you need to escape them like so

mkdir new\ folder

This creates a directory called "new folder"

Note the \ is right after word "new"

 

so to cd into "Summer 2009"

 

cd Summer\ 2009

 

Thanks for the suggestion, but Im not making the folders, and also they arent being made via command line or on linux for that matter.

Posted
try:

 

chaning $directory on line 6 to

${directory/ /\\ }

 

that should subsitute all the spaces in $directory to "\ "

 

you will have to do it for file name aswell because "random picture.jpg" will be treated as "random" and "picture.jpg"

 

I tried that, it didnt seem to work. Same error as before

 

 cd: 2009: No such file or directory
mv: cannot stat `*.jpg': No such file or directory

Posted
mv: cannot stat `*.jpg': No such file or directory

 

That seems to imply that its taking "*" as a literal character, which athough isnt your current problem, might come up later

Posted

Ah, wait, I misread your question. Try this:

 

for directory in $(find . -type d)
do (cd $directory
for file in `ls *.jpg`

do mv $file /Photos/new
....

 

This shells out to ls to get a list of .jpg files and works off that, instead of using the string literal '*.jpg'.

Posted (edited)

Arcath the problem isnt with the *.jpg, as it works fine with non spaced directories

 

The problem is the script cant change directory into a directory with a space, and therefore there are no jpg files for it to move, as the folder it tries to change into doesnt exist

 

Edit: The folder name as is "Summer 2009" so the full error it gives is:

 

 

cd: Summer: No such file or directory

mv: cannot stat `*.jpg': No such file or directory

cd: 2009: No such file or directory

mv: cannot stat `*.jpg': No such file or directory

 

(sorry should have posted the full error more clearly)

Edited by RabbieBurns
Posted

You might also find this easier (note: untested) as I think all you're trying to do is find .jpg files in a tree, and move them all into one place.

 

find . -name *.jpg -type f -print0 | xargs -0 mv '{}' /Photos/new

 

One line to rule them all, one line to find them, one line to bring them all and in the darkness replace your whole script :D

 

Your friends are 'man find' and 'man xargs'.

  • Thanks 1
Posted
You might also find this easier (note: untested) as I think all you're trying to do is find .jpg files in a tree, and move them all into one place.

 

find . -name *.jpg -type f -print0 | xargs -0 mv '{}' /Photos/new

 

One line to rule them all, one line to find them, one line to bring them all and in the darkness replace your whole script :D

 

Your friends are 'man find' and 'man xargs'.

 

"I think all you're trying to do is find .jpg files in a tree, and move them all into one place" <-- Yep thats exactly what Im attempting.

 

Im not quite sure what this error means?

 

roberts Photos # find . -name *.jpg -type f -print0 | xargs -0 mv '{}' /Photos/new
mv: target `./new/Summer 2009/summer2.jpg' is not a directory

Posted

roberts Photos # find . -type f -name "*.jpg" -exec mv {} /tmp  \;
roberts Photos # ls /tmp
1.jpg  2.jpg  holiday.jpg

 

Yep. Thanks.

 

So, does this mean that I cant use /Photos/new as the destination to move photos from /Photos/new/blah blah ?

Posted (edited)

Im not quite sure what this error means?

 

roberts Photos # find . -name *.jpg -type f -print0 | xargs -0 mv '{}' /Photos/new
mv: target `./new/Summer 2009/summer2.jpg' is not a directory

 

Sorry, my mistake. It should read:

 

find . -name *.jpg -type f -print0 | xargs -0 --replace mv '{}' /Photos/new

 

 

As an aside, using find with -exec results in one forked process per file processed, wheras using xargs puts as many files as possible into one call to mv, so one forked process per many, many files. If you're moving lots of things around, you'll probably notice the difference.

 

 

Edit: another thought, you can also use -i instead of --replace in your call to xargs.

Edited by powdarrmonkey
  • Thanks 2
Posted

As an aside, using find with -exec results in one forked process per file processed, wheras using xargs puts as many files as possible into one call to mv, so one forked process per many, many files. If you're moving lots of things around, you'll probably notice the difference.

 

Thats useful to know, I never quite got the hang of xargs but will endeavor to learn!

Posted

roberts Photos # find . -name *.jpg -type f -print0 | xargs -0 --replace mv '{}' /Photos/new
find: paths must precede expression: 2.jpg
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

 

roberts Photos # find . -name *.jpg -type f -print0 | xargs -0 -i mv '{}' /Photos/new
find: paths must precede expression: 2.jpg
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

 

I appreciate your help. (PS. The file 2.jpg is in /Photos/, which is where Im running the command)

Posted

Damn, it's really not going well for me today :( Wrap your *.jpg in quotes to stop bash interpreting it, like "*.jpg". Otherwise, bash tries to give find a list of files that it think it should be finding, and find gets grumpy.

 

@Cybernerd: All it does it turn

mv 1.jpg /tmp
mv 2.jpg /tmp
mv 3.jpg /tmp
mv 4.jpg /tmp
mv 5.jpg /tmp
mv 6.jpg /tmp
mv 7.jpg /tmp

 

into

mv 1.jpg 2.jpg 3.jpg 4.jpg 5.jpg 6.jpg 7.jpg /tmp

 

but also does some sanity checking, like making sure that the list of arguments isn't so long as to cause a buffer overflow (in which case, splits it into two calls).

  • Thanks 1

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 account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...