510 For me when I open the shell the output is something like: :: |
510 For me when I open the shell the output is something like: :: |
511 |
511 |
512 Good Morning baali, Have a nice day! |
512 Good Morning baali, Have a nice day! |
513 This is Wednesday 16 in September of 2009 (11:54:47 AM IST) |
513 This is Wednesday 16 in September of 2009 (11:54:47 AM IST) |
514 |
514 |
515 Loops and Control Structures: |
515 Loops |
516 ----------------------------- |
516 ----- |
|
517 |
|
518 Bash has three different commands for looping -- ``for``, ``while`` and ``until``. |
|
519 |
|
520 ``for`` loop |
|
521 ~~~~~~~~~~~~ |
|
522 |
|
523 Suppose we have a set of files, that have names beginning with numbers followed by their names - ``08 - Society.mp3``. We would like to rename these files to remove the numbering. How would we go about doing that? It is clear from the problem statement that we could use a ``for`` loop, to loop through the list of files and rename each of the files. |
|
524 |
|
525 Let's first look at a simple ``for`` loop, to understand how it works. |
|
526 :: |
|
527 |
|
528 for animal in rat cat dog man |
|
529 do |
|
530 echo $animal |
|
531 done |
|
532 |
|
533 We just wrote a list of animals, each animal's name separated by a space and printed each name on a separate line. The variable ``animal`` is a dummy variable and has no significance. You could use something as lame as ``i`` in place of ``animal``. |
|
534 |
|
535 Now, we use a simple ``for`` loop to list the files that we are interested in. |
|
536 :: |
|
537 |
|
538 ls *.mp3 > list |
|
539 for i in `cat list` |
|
540 do |
|
541 echo "$i" |
|
542 done |
|
543 |
|
544 If your filenames contain spaces, ``for`` assumes each space separated word to be a single item in the list and prints it in a separate line. We could change the script slightly to overcome this problem. |
|
545 :: |
|
546 |
|
547 for i in *.mp3 |
|
548 do |
|
549 echo "$i" |
|
550 done |
|
551 |
|
552 Now, we have each file printed on a separate line. Depending on the files that we have we could use grep to get the relevant portion of the filenames and rename the files. |
|
553 :: |
|
554 |
|
555 for i in *.mp3 |
|
556 do |
|
557 j=$(echo "$i"|grep -o "[A-Za-z'&. ]*.mp3") |
|
558 echo "$i -> $j" |
|
559 done |
|
560 |
|
561 Now we just replace the echo command with a ``mv`` or a ``cp`` command. |
|
562 :: |
|
563 |
|
564 for i in *.mp3 |
|
565 do |
|
566 j=$(echo "$i"|grep -o "[A-Za-z'&. ]*.mp3") |
|
567 cp "$i" "$j" |
|
568 done |
|
569 |
|
570 As an exercise, you could try sorting the files in reverse alphabetical order and then prefix numbers to each of the filenames. |
|
571 |
|
572 ``while`` |
|
573 ~~~~~~~~~ |
|
574 |
|
575 The ``while`` command allows us to continuously execute a block of commands until the command that is controlling the loop is executing successfully. |
|
576 |
|
577 Let's start with the lamest example of a while loop. |
|
578 :: |
|
579 |
|
580 while true |
|
581 do |
|
582 echo "True" |
|
583 done |
|
584 |
|
585 This, as you can see, is an infinite loop that prints the ``True``. |
|
586 |
|
587 Say we wish to write a simple program that takes user input and prints it back, until the input is ``quit``, which quits the program. |
|
588 :: |
|
589 |
|
590 while [ "$variable" != "quit" ] |
|
591 do |
|
592 read variable |
|
593 echo "Input - $variable" |
|
594 done |
|
595 exit 0 |
|
596 |
|
597 ``until`` |
|
598 ~~~~~~~~~ |
|
599 |
|
600 The ``until`` loop is similar to the ``while`` loop, except that it executes until the conditional command does not execute properly. |
|
601 |
|
602 The infinite loop changes to the following, when ``until`` is used. |
|
603 :: |
|
604 |
|
605 until false |
|
606 do |
|
607 echo "True" |
|
608 done |
517 |
609 |
518 |
610 |
519 Further Reading: |
611 Further Reading: |
520 ---------------- |
612 ---------------- |
521 * http://www.freeos.com/guides/lsst/ |
613 * http://www.freeos.com/guides/lsst/ |