Saturday, February 13, 2010

Prompt Tricks 2

I'm a little behind because of all the snow, but fortunately ace book reviewer Mark Polesky has come to my rescue with some feedback on my previous post.  He writes:

That's a pretty cool script, but the formatting of the
output is a little sloppy.  If nothing else this line is in
the wrong place:

  printf '\033[0m'

Here's a much cleaner version using bash.

- Mark

* * * * * * * * * *


# prompt-colors -- demonstrate prompt color combinations.

for attr in 0 1 4 5 7; do
  printf "ESC[%s;Foreground;Background\n" $attr
  for fore in {30..37}; do
    for back in {40..47}; do
      printf '\033[%s;%s;%sm %02s;%02s ' \
        $attr $fore $back $fore $back
    printf '\033[0m\n'

Good job, Mark (he has become a real command line ninja since he read my book from cover to cover as a reviewer).

One of the interesting things Mark did in converting the script from plain sh to bash was to employ brace expansion in the for commands.  For example:

for fore in {30..37}; do

This expansion results in a sequence of numbers from 30 to 37 inclusive, a good technique to know.

But what if you need to produce a sequence of numbers that increment by a value other than one?  Let's say that you only wanted odd numbers from 1 to 7?  In this case, you could code the sequence literally:

for i in 1 3 5 7; do

That's easy, but what about a sequence from 1 to 777?  Not so easy.

To produce a large sequence, you can use the seq command.  It works like this:

seq [-options] [first [increment]] last

where first is the first number in the desired sequence, increment is the size of the step between each member of the sequence and last is the last number in the sequence.  For example, to produce a sequence of odd numbers from 1 to 777, we would do this:

for i in $(seq 1 2 777); do

The seq command is also handy if you need to ensure that a script can run under sh since sh lacks the brace expansion feature of bash.

Well, that's all I have.  Got to get back to shoveling!

Further Reading