Move several files into specific directories with a loop

Hello,

I'm a first time poster looking for help in scripting a task in my daily routine. I am new in unix but i am attracted to its use as a mac user.

Bear with me...

I have several files (20) that I manually drag via the mouse into several named directories over a network. I've used rsync to copy files from directories but i don't know how to move or copy the 20 jpgs into the corresponding 20 directories which have 01-20 as identifiers.
In other words, each jpg goes into a ]01_filename_100px
02_filename_200px...so on til
20_filename _3000px

I have searched the web for several days without an intelligent answer...

I believe I need an expression or a loop to accomplish this. I tried applescript, automator and rsync but I reached frustration... :frowning:

Ideally I would like to use a standard mac process, like terminal.

Can someone point me to a resource? a book? a link?

Thanks

SonnyClark

Do you know how to use the terminal on the mac?

I ask this because in your question, you mention "dragging".....

The task you are describing is a "terminal" level task, not a GUI "draggable" task (generally speaking).

Neo,
Thanks for the quick reply and the answer to your question is yes. I use the terminal for copying files with rsync.

For my posted question, however, I've been using the mouse on my mac to drag the files to the folders.

SonnyClark

I am rewriting my question for clarity. Please, please help me!

I have the following challenge which I am trying to solve via bash with an expression that takes the suffix of the file and the prefix of the folder as a target or another type of loop formula.

I'd like to move files with sequential numbers into existing sequential numbered directories. like:

filename_01.jpg   into folder name   01_foldername
filename_02.jpg   into folder name   02_foldername
filename_03.jpg   into folder name   03_foldername... so on...

I tried the following without much success

for f in *files2folders; do
  target_part="${E[0-9][0-9]}"
  target="${E[0-9][0-9]}"
  mv "$f" -t "${target} "*
done

I am a new linux student and would love explore this solution.

Could someone help me with a link or a tutorial to accomplish this?
I am using my shell terminal in a mac os environment.

How is that "without much success" expressed? Error messages / warnings? Unexpected results? Explain...

A decent, detailed, consistent, complete specification pays off as you might get better replies, and sooner.

Your code sample wouldn't find any of the files in your data sample. Your variable assignments will give error messages.

The error I get from terminal:
-bash: E: bad array subscript
-bash: E: bad array subscript
The files and directories are located on my desktop in a directory called "files2folders"

Please, please - provide us with the info needed! Getting the entire context here is like pulling teeth!

Based on some guesswork on what your request and environment are, I came up with

for FN in files2folders/*.jpg
  do    TN="${FN%.*}_foldername"
        echo mv "$FN" "${FN%%/*}/${TN#*_}"
  done
mv files2folders/filename_01.jpg files2folders/01_foldername
mv files2folders/filename_02.jpg files2folders/02_foldername
mv files2folders/filename_03.jpg files2folders/03_foldername

remove the echo in case you're happy with what you see. How far would that get you?

I'm sorry, I realize I may be over-explaining.
my parent directory is: files2folders
inside the parent are 4 directories and 4 files:

01_webasset_100
02_webasset_200
03_webasset_300
04_webasset_400

1244081312562_01.jpg
1244081312562_02.jpg
1244081312562_03.jpg
1244081312562_04.jpg

I want to put each of those files into those folders using the file number suffixes and folder prefixes as "strings"?...

Thanks

Start with a decent spec in the first place.

Try

cd files2folders
for FN in *.jpg
  do    NR="${FN%.*}"
        NR="${NR#*_}"
        echo mv "$FN"  "$NR"*
  done
mv 1244081312562_01.jpg 01_webasset_100
mv 1244081312562_02.jpg 02_webasset_200
mv 1244081312562_03.jpg 03_webasset_300
mv 1244081312562_04.jpg 04_webasset_400
 

Above may fail if you have directories with non-unique starting numbers so that "$NR"* evaluates to multiple dirs.

1 Like

Rudi,
Fantastic!
It works like a charm.
Would you mind explaining the code for my learning?

Thanks soooooo much!

After changing directory to "files2folders", the for loop runs across all .jpg files. The "number suffixes" are extracted by means of two shell's "Parameter Expansion / Remove matching prefix (suffix) pattern" ( man bash ), then the mv command is constructed using the FN and NR variables, relying on the assumption that there will be only ONE matching directory.

1 Like

Hi
And if we assume that there are more files than directories

touch files2folders/1244081312563_04.jpg
cd files2folders
find *[1-4]00 -prune -type d -exec bash -c 'echo mv *_${0/%_*/.jpg} $0' {} \;

mv 1244081312562_01.jpg 01_webasset_100
mv 1244081312562_02.jpg 02_webasset_200
mv 1244081312562_03.jpg 03_webasset_300
mv 1244081312562_04.jpg 1244081312563_04.jpg 04_webasset_400

or
Bring them back

find *[1-4]00 -prune -type d -exec bash -c 'mv $0/*.jpg ./' {} \;
#!/bin/bash
cd files2folders
for FN in *[1-4]00; do
        echo mv *_${FN/%_*}.jpg $FN
done

mv 1244081312562_01.jpg 01_webasset_100
mv 1244081312562_02.jpg 02_webasset_200
mv 1244081312562_03.jpg 03_webasset_300
mv 1244081312562_04.jpg 1244081312563_04.jpg 04_webasset_400

Thank you nezabudka,
I can't wait to try that.
Question, what if there is a letter code preceding the suffix on the filename like filename_wa01.jpg? would i ruin the code if i added the "wa" to the string? Sorry i am newbie...

touch filename_wa01.jpg

patterns should change to the following

find *[1-4]00 -prune -type d -exec bash -c 'echo mv *[!0-9]${0/%_*/.jpg} $0' {} \;

and

for FN in *[1-4]00; do
	echo mv *[!0-9]${FN/%_*}.jpg $FN
done
mv 1244081312562_01.jpg filename_wa01.jpg 01_webasset_100
mv 1244081312562_02.jpg 02_webasset_200
mv 1244081312562_03.jpg 03_webasset_300
mv 1244081312562_04.jpg 1244081312563_04.jpg 04_webasset_400

Might be wise not to rely on the directories' suffixes correspond to their "sequential number" which equals the files' "sequential numbers". And, check if a corresponding file exists at all to avoid failure if absent:

for DN in 0[1-4]*
  do    TMP="*[!0-9]${DN/%_*}.jpg"
        [ -f $TMP ] && echo mv $TMP $DN
  done
mv 1244081312562_02.jpg 02_webasset_200
mv 1244081312562_03.jpg 03_webasset_300
mv 1244081312562_04.jpg 04_webasset_400

as opposed to

mv *[!0-9]01.jpg 01_webasset_100
mv 1244081312562_02.jpg 02_webasset_200
mv 1244081312562_03.jpg 03_webasset_300
mv 1244081312562_04.jpg 04_webasset_400

without the precautions.