LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

Reply
 
Search this Thread
Old 07-16-2008, 12:22 PM   #1
leupi
Member
 
Registered: Mar 2004
Location: Annapolis, Maryland, USA
Distribution: Ubuntu 11.04, Mint 11.11, Xubuntu 11.11
Posts: 457

Rep: Reputation: 30
Script to create folders and subfolders


I need to create a lot of folders and subfolders and was wondering how I might write a script to do this. I need to have a top level folder, 'images' and under that, subfolders numbered sequentially, '100', 101', 102', etc. Within those subfolders I need three additional folders, '192x128', '384x256', and '768x512'. The second level folders (the sequential ones) will number anywhere from ten to 100 folders. Any thoughts on how I can do this?

I am using ImageMagick to resize images in one set of folder and I need to move them over to this new set and unfortunately the folder structure is not the same as where I am getting the images.

Thanks,
Todd
 
Old 07-16-2008, 12:34 PM   #2
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,695
Blog Entries: 5

Rep: Reputation: 240Reputation: 240Reputation: 240
please do man mkdir
 
Old 07-16-2008, 12:53 PM   #3
cmnorton
Member
 
Registered: Feb 2005
Distribution: Ubuntu, CentOS
Posts: 585

Rep: Reputation: 35
There's more

As an aside, you are more likely to get help by starting this process, and then asking for help.

First, create the script file name using a text editor. Depending what shell you want it to run -- bash -- make sure the first line is #!/bin/bash. On Red Hat systems #!/bin/sh links to /bin/bash, but that is not guaranteed on other distros.

Don't forget to protect the file chmod 775 <script_file_name>, and invoke it (run it) using ./ in front of the script name.

Then, look through man bash and/or try this link to find out about for loops

http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html

You could probably put all your resolution directories in one of those for loops and then use mkdir within the loop.

3) It also helps for you and those answering you to know your distribution.
 
Old 07-16-2008, 12:53 PM   #4
leupi
Member
 
Registered: Mar 2004
Location: Annapolis, Maryland, USA
Distribution: Ubuntu 11.04, Mint 11.11, Xubuntu 11.11
Posts: 457

Original Poster
Rep: Reputation: 30
man mkdir is one of the first places that I looked. I feel that my needs are a bit more involved than what I can get out of simply the mkdir command. I would imagine that I will need to do some scripting that is a bit more involved than what I am familiar with.

Thanks,
Todd
 
Old 07-16-2008, 01:12 PM   #5
colucix
Moderator
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,458

Rep: Reputation: 1941Reputation: 1941Reputation: 1941Reputation: 1941Reputation: 1941Reputation: 1941Reputation: 1941Reputation: 1941Reputation: 1941Reputation: 1941Reputation: 1941
Quote:
Originally Posted by leupi View Post
I feel that my needs are a bit more involved than what I can get out of simply the mkdir command.
Not really...
Code:
mkdir -p images/{100..110}/192x128
mkdir -p images/{100..110}/384x256
mkdir -p images/{100..110}/768x512
in bash the {N..M} syntax produces a sequence of integers from N to M. You should start to read a good bash programming guide for future reference. You can accomplish a lot of tasks in a bunch of seconds using parameter substitution, loops, and so on.
 
Old 07-16-2008, 01:15 PM   #6
leupi
Member
 
Registered: Mar 2004
Location: Annapolis, Maryland, USA
Distribution: Ubuntu 11.04, Mint 11.11, Xubuntu 11.11
Posts: 457

Original Poster
Rep: Reputation: 30
Thanks for the info. I will work on this later when I get home. Seems like I need to set up a 'while' statement to create the first level directories and set up a counter and keep creating directories till the counter increments to a set number. Then I'll need to figure out a way to populate each one of those new directories with three more subdirectories, '192x128', '384x256', and '768x512'. Does that sound like I am on the right track?

Thanks,
Todd
 
Old 07-16-2008, 01:18 PM   #7
leupi
Member
 
Registered: Mar 2004
Location: Annapolis, Maryland, USA
Distribution: Ubuntu 11.04, Mint 11.11, Xubuntu 11.11
Posts: 457

Original Poster
Rep: Reputation: 30
calucix,

Thanks, that sounds like what I need! I just bought 'Learning the Bash Shell' by O'Reilly so I'm sure that that will be a big help. I appreciate the insight. I will be doing a lot of this and this script will be a big time saver for me.

Thanks,
Todd
 
Old 07-16-2008, 01:25 PM   #8
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 62
As colucix pointed out, the {n..m} expansion works. You can also use {a,b,c} which will expand to "a" and b" and "c". Combining them, you can quickly make a long list of strings. For example:
Code:
% echo {1..3}{a,b}
1a 1b 2a 2b 3a 3b
instead of passing this list of strings to echo, you can pass their straight to mkdir:
Code:
mkdir -p images/{100..110}/{192x128,384x256,768x512}
The -p option makes it possible makes multi-level sub-directories without a problem. Without it, you have to create "images" before you can create "images/100" and so on.
 
Old 07-16-2008, 01:34 PM   #9
leupi
Member
 
Registered: Mar 2004
Location: Annapolis, Maryland, USA
Distribution: Ubuntu 11.04, Mint 11.11, Xubuntu 11.11
Posts: 457

Original Poster
Rep: Reputation: 30
Matt,

That worked beautifully, that did exactly what I needed, and it was so simple. Now I just need to play with ImageMagick and get the resized files in the appropriate places and I am set. I think that I am going to have to get more familiar with bash, this can be quite the time saver. Thanks so much for everything!

Todd
 
Old 07-16-2008, 01:50 PM   #10
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 62
Yeah, shell scripting can be a really boost to productivity. It's not always pretty, but for things like this, you can often spend 2 minutes doing what would take 2 hours with GUI tools.
 
Old 07-18-2008, 09:06 AM   #11
leupi
Member
 
Registered: Mar 2004
Location: Annapolis, Maryland, USA
Distribution: Ubuntu 11.04, Mint 11.11, Xubuntu 11.11
Posts: 457

Original Poster
Rep: Reputation: 30
I completed my project (thanks to you guys) and all went rather well. It went so well in fact that I was handed another one (gotta love working for a nonprofit...). This one is very similar with a bit of a twist. I will have a directory with subdirectories which include images. The subdirectories could be one or more levels deep. I need to convert all of the images to thumbnails and maintain the existing directory structure.

I was looking for a script that would recursively drill down into the directories and convert and images to thumbnails. I found this script and am trying to decipher it:
Code:
new=order-thumb
mkdir /d1/$new
for i in $(find /photo1 -name "*jpg"); do 
    img=$(basename $i);dir=$(dirname $i)
    if [ ! -d $new/$dir ]; then mkdir -p $new/$dir; fi
    convert -size 500x500 -geometry 500x500 $i $new/$dir/$img
done
I have my 'Learning the bash Shell' book that I am flipping through trying to translate, but if anyone could offer their expertise that would be greatly appreciated.

Thanks again for everyone's previous help,

Todd
 
Old 07-18-2008, 09:23 AM   #12
0.o
Member
 
Registered: May 2004
Location: Raleigh, NC
Distribution: Debian, Solaris, HP-UX, AIX
Posts: 208

Rep: Reputation: 35
Code:
#This sets a variable
new=order-thumb
#This creates the directord /dl/order-thumb
mkdir /d1/$new

#This uses the output of the find command
#and assigns it to the variable 'i'
for i in $(find /photo1 -name "*jpg"); 
     do 

#For each element found above, assign the image filename
#to the 'img' variable and the path to 'dir'.
         img=$(basename $i);
         dir=$(dirname $i);

#Here we are checking for the directory order-thumb
         if [ ! -d $new/$dir ];
            then 
                #If the above directory doesn't exist, create it.
                mkdir -p $new/$dir; 
         fi
            #Convert the images and place them into their new directory.
            convert -size 500x500 -geometry 500x500 $i $new/$dir/$img
     done
 
Old 07-18-2008, 10:39 AM   #13
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 62
If you put
Code:
set -vx
on the line after the #!/bin/bash line in your script, each statement will be printed after it is read from the file, and also after doing expansion of the command (like putting in the values of variables and so on).

With long scripts, this will often create so much output that you get swamped, but for small fragments it can be very helpful to understand what is going on. for example:
Code:
#!/bin/bash
set -vx
cd $HOME/tmp/test
ls -l *.txt
for f in *.txt; do
  echo "oh hai $f"
done
That will produce this output:
Code:
cd $HOME/tmp/test
+ cd /home/matthew/tmp/test
ls -l *.txt
+ ls -l one.txt three.txt two.txt
-rw-r--r-- 1 matthew matthew 0 2008-07-18 16:18 one.txt
-rw-r--r-- 1 matthew matthew 0 2008-07-18 16:19 three.txt
-rw-r--r-- 1 matthew matthew 0 2008-07-18 16:18 two.txt
for f in *.txt; do
  echo "oh hai $f"
done
+ for f in '*.txt'
+ echo 'oh hai one.txt'
oh hai one.txt
+ for f in '*.txt'
+ echo 'oh hai three.txt'
oh hai three.txt
+ for f in '*.txt'
+ echo 'oh hai two.txt'
oh hai two.txt
...which I hope is useful.

I would like to point out that you might run into problems when there are files with spaces in the file name. Whenever you are iterating over a list of strings, it is prudent to use "double quotes" when taking the value of the iterator variable ($i in this case).

Consider this example:
Code:
touch "file1.txt" "file 2.txt"
for f in *.txt; do
    ls -l $f
done
Here you will have a problem with "file 2.txt" because the ls line will look like this to the shell:
Code:
ls -l file 2.txt
...which it interprets as a request to list two files: "file" and "2.txt".
To correct it, you should add double quotes when using the iterator operator:
Code:
for f in *.txt; do
    ls -l "$f"
done
This is a very a common mistake and can often be difficult to debug if files with spaces in the name are only created some time after the script is written and tested. For this reason, I think it's a good idea to get into the habit of using double quotes when taking the value of variables, even when it is not strictly necessary... just to set that pattern of using the quotes so that you won't fail to do so when it is necessary.

In the case where you are calling find like this, it is worse:
Code:
for i in $(find /photo1 -name "*jpg"); do
    ...
done
Here, the bit inside the $(...) is executed as a shell command, and then the result is split up with IFS being used as a delimiter. In this case, there is no way for the shell to know if there is a space within a file name.

A better construct is like this:
Code:
find /photo1 -name "*.jpg" | while read i; do
    ...
done
There the output of the find command is read line-by-line and each line is read into the i variable. This method will cope with spaces in file names. You still need to remember quote the $i when you use it.

This still does not cope with the case where there is a new line character in a file name, but it's probably safe to assume that you won't encounter that very often.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Cannot create folders with bash script called from php keyF Linux - Software 4 06-25-2006 10:58 AM
Samba can create new files and folders but access denied in any new folders k.king Linux - Networking 2 01-15-2006 06:14 AM
need a script to delete all files from a folder and subfolders cccc Programming 1 03-04-2005 10:54 AM
Changing permission of folders and subfolders pablowablo Linux - Newbie 2 07-28-2004 12:11 AM
Mozilla 1.6 can't create subfolders porty Linux - Software 0 05-19-2004 01:48 PM


All times are GMT -5. The time now is 06:07 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration