Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

clilly

macrumors newbie
Original poster
Jan 23, 2023
9
1
Hello, I need to automate copy/moving a single file to multiple folders at once. The folders will be numbered sequentially (1000-1050, for example). I can copy/move the file to one folder at a time using cp example.jpg 1000. How do I copy/move it to say, 1000 through 1050? There will be a different series of folders each day, but always numbered sequentially.

I'm a newbie at this, I imagine this is super basic, but I could only find information about how to move multiple items to a single folder. The opposite of what I'm doing.
 
Hello, I need to automate copy/moving a single file to multiple folders at once. The folders will be numbered sequentially (1000-1050, for example). I can copy/move the file to one folder at a time using cp example.jpg 1000. How do I copy/move it to say, 1000 through 1050? There will be a different series of folders each day, but always numbered sequentially.

I'm a newbie at this, I imagine this is super basic, but I could only find information about how to move multiple items to a single folder. The opposite of what I'm doing.


You can do a similar thing to what we did when we created the folders in your prior thread. So instead of mkdir $I, you will do cp/mv (copy or move) fileName $i/filename and it should do it for each folder
 
Hello again, and thanks. What I ended up doing was mkdir {xxxx..xxxx}. $ seems to be over my head, as terminal came back with "no such file or directory".

I tried cp filename {1000..1010} and got back cp: xxxx is a directory (not copied) for each folder.
Per your instructions, I just tried cp/mv infocard1.jpg $i/infocard1.jpg and got back "no such file or directory"

if cp filename 1000 works, is there a way to replace "1000" with "1000-1015"?
 
Shell scripting is a fickle beast. It may be worthwhile to find a beginner shell tutorial online to familiarize yourself with the basic utilities and syntax.

When you say mkdir {1..5}, the shell expands that into mkdir 1 2 3 4 5. When executed, the program mkdir steps through each argument and creates a directory of the same name in the current directory.

When you say cp filename {1..5}, the shell expands that into cp filename 1 2 3 4 5. When executed, the program cp attempts to copy all the arguments, except the last one, into the final argument. So what it tried to do was copy the file filename and directories 1, 2, 3, and 4 into directory 5 (which isn't what you wanted to do). For completeness, the errors you got were because, being a potentially expensive operation, cp doesn't copy directories by default. If you wanted to copy directories, you add the -r option to the command.

What you want is a for loop, as @kryten2 suggested in your other post:
Your shell whatever that may be might be useful.
Example:
Bash:
for i in {1000..1100}; do mkdir $i; done
This iterates through every number in the sequence 1000–1100 and assigns the current number to the variable named i, a common shorthand for "index". The $i expands/reads the variable, replacing it with the current number being handled. This is functionally equivalent to:
Bash:
mkdir 1000
mkdir 1001
mkdir 1002
...

So for your particular situation, you would want:
Bash:
for i in {1000..1100}; do cp infocard1.jpg $i/; done
Which does:
Bash:
cp infocard1.jpg 1000/
cp infocard1.jpg 1001/
cp infocard1.jpg 1002/
...
If the final argument is a directory (as above), cp will copy the file into that directory with the same name. If you wanted to be more verbose, you could write something like:
Bash:
for ProductNumber in {1000..1100}; do
    cp infocard1.jpg $ProductNumber/infocard1.jpg
done

This just scratches the surface of what you can do with shell scripts – the only limit is your imagination. Hopefully this whets your appetite enough to learn more on your own.
 
Shell scripting is a fickle beast. It may be worthwhile to find a beginner shell tutorial online to familiarize yourself with the basic utilities and syntax.

When you say mkdir {1..5}, the shell expands that into mkdir 1 2 3 4 5. When executed, the program mkdir steps through each argument and creates a directory of the same name in the current directory.

When you say cp filename {1..5}, the shell expands that into cp filename 1 2 3 4 5. When executed, the program cp attempts to copy all the arguments, except the last one, into the final argument. So what it tried to do was copy the file filename and directories 1, 2, 3, and 4 into directory 5 (which isn't what you wanted to do). For completeness, the errors you got were because, being a potentially expensive operation, cp doesn't copy directories by default. If you wanted to copy directories, you add the -r option to the command.

What you want is a for loop, as @kryten2 suggested in your other post:

This iterates through every number in the sequence 1000–1100 and assigns the current number to the variable named i, a common shorthand for "index". The $i expands/reads the variable, replacing it with the current number being handled. This is functionally equivalent to:
Bash:
mkdir 1000
mkdir 1001
mkdir 1002
...

So for your particular situation, you would want:
Bash:
for i in {1000..1100}; do cp infocard1.jpg $i/; done
Which does:
Bash:
cp infocard1.jpg 1000/
cp infocard1.jpg 1001/
cp infocard1.jpg 1002/
...
If the final argument is a directory (as above), cp will copy the file into that directory with the same name. If you wanted to be more verbose, you could write something like:
Bash:
for ProductNumber in {1000..1100}; do
    cp infocard1.jpg $ProductNumber/infocard1.jpg
done

This just scratches the surface of what you can do with shell scripts – the only limit is your imagination. Hopefully this whets your appetite enough to learn more on your own.
Hello! Thank you for this! So, basically, you define the range first. That's where I was getting stuck. I was able to make this work:

for i in {1000..1100}; do cp infocard1.jpg $i/; done

This is so helpful. Makes sense to look into a more thorough foundation in this subject should I need to do a lot of things like this.
 
Hello! Thank you for this! So, basically, you define the range first. That's where I was getting stuck. I was able to make this work:

for i in {1000..1100}; do cp infocard1.jpg $i/; done

This is so helpful. Makes sense to look into a more thorough foundation in this subject should I need to do a lot of things like this.
Yep :)

Out of curiosity how did your first attempt look? Since this is basically what was written by someone else in the other thread for the making of directories
 
When you said the thing above. How was your first attempts at using the $ different?
I think what I did was not define the range first, if that's the right way to say it - so left out: for i in {1000..1100}. I was confused because I didn't understand how $ could communicate anything specific.

"for i in {1000..1100}; do cp infocard1.jpg $i/; done" is working great. I just have to use the cd command to "navigate" the terminal to the right folder--I'm sure my way of conceptualizing it is probably way off, but that's how it's making sense to my non developer mind. Then put one copy of the infocard in folder that contains the series of folders I've created that day and use the command. I assume I could tell the terminal where the infocard is located, but it takes 10-15 seconds, once a day at the most, I'm not sure it'd be that much faster.
 
I think what I did was not define the range first, if that's the right way to say it - so left out: for i in {1000..1100}. I was confused because I didn't understand how $ could communicate anything specific.

"for i in {1000..1100}; do cp infocard1.jpg $i/; done" is working great. I just have to use the cd command to "navigate" the terminal to the right folder--I'm sure my way of conceptualizing it is probably way off, but that's how it's making sense to my non developer mind. Then put one copy of the infocard in folder that contains the series of folders I've created that day and use the command. I assume I could tell the terminal where the infocard is located, but it takes 10-15 seconds, once a day at the most, I'm not sure it'd be that much faster.
That makes sense. For reference, $ in (most) shells binds a reference. It means that the identifier that comes after it is a variable not a filename or similar. Or at least in contexts like this that's what it means :)
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.