Tag Archives: Automation

Taking BASH automation deeper down the rabbit hole

Automaton at your service!

The BASH (or rather, any Linux) shell is like a programming environment in itself: you can do pretty simple stuff with it, and you can do increasingly crazy stuff with it if you wish to venture there… Here’s one way to do some simple automating of stuff using the for-do-done construct in BASH:

Here we have for our example three folders, each containing three files.

$ ls -l
total 12
drwxr-xr-x 2 user user 4096 2012-08-31 13:58 folder1
drwxr-xr-x 2 user user 4096 2012-08-31 13:58 folder2
drwxr-xr-x 2 user user 4096 2012-08-31 13:58 folder3

$ ls -l *
folder1:
total 36
-rw-r--r-- 1 user user 0 2012-08-31 13:58 file1
-rw-r--r-- 1 user user 0 2012-08-31 13:58 file2
-rw-r--r-- 1 user user 0 2012-08-31 13:58 file3

folder2:
total 36
-rw-r--r-- 1 user user 0 2012-08-31 13:58 file4
-rw-r--r-- 1 user user 0 2012-08-31 13:58 file5
-rw-r--r-- 1 user user 0 2012-08-31 13:58 file6

folder3:
total 36
-rw-r--r-- 1 user user 0 2012-08-31 13:58 file7
-rw-r--r-- 1 user user 0 2012-08-31 13:58 file8
-rw-r--r-- 1 user user 0 2012-08-31 13:58 file9

A simple loop to do something (like echoing out their names here) on each of the items in the working folder. This is the basic structure of a for-do-done loop in BASH:

$ for i in *;
>     do echo $i;
> done
folder1
folder2
folder3

This can be condensed into a single line for easy copy-and-pasting:

$ for i in *; do echo $i; done
folder1
folder2
folder3

Now, let’s go a little deeper and work with each file within each subdirectory here. For that we just nest another for loop within the outer one. Note that there’re commands to change the working directory in and out of the subdirectory each round:

$ for i in *;
>     do echo $i;
>     cd $i;
>     for j in *;
>         do echo "$i - $j";
>     done;
>     cd ..;
> done
folder1
folder1 - file1
folder1 - file2
folder1 - file3
folder2
folder2 - file4
folder2 - file5
folder2 - file6
folder3
folder3 - file7
folder3 - file8
folder3 - file9

And as you might have guessed, combining all these into a single line is possible too…

$ for i in *; do echo $i; cd $i; for j in *; do echo "$i - $j"; done; cd ..; done
folder1
folder1 - file1
folder1 - file2
folder1 - file3
folder2
folder2 - file4
folder2 - file5
folder2 - file6
folder3
folder3 - file7
folder3 - file8
folder3 - file9

How deep you nest the for loops depends on what you need, and how crazymotivated you are to create and troubleshoot such a monster. Good luck!

HTH.