PRODUCT






Home









Free Download








Installation Instructions





FAQ





FAQ








Ask A Question





LEARN SCRIPTING





Overview








Lesson 1








2


3


4


5








Exam





SAMPLE SCRIPTS





Computer








Internet








Administrators








Developers








Data








Miscellaneous





HELP / DOCUMENTATION





Commands








Automated Internet








Automated Editors








Sample Scripts








Precompiled Functions








System Features






Learning Scripting - Lesson 4
(File Directory Loop, af Command, if-else-endif, Argument Passing - FVA)

In this lesson, we will see a very powerful, and commonly used scripting technique called the File Directory Loop. I will introduce you to the af command. I will also show you how to execute commands conditionally using if-else-endif. Finally, I will present the concept of FVA (Forward Variable Assignment) used in argument passing.



PREPARATION
  1. Did you understand the important concepts in the last lesson ? If not, please take a look at that lesson again. Look at the words, phrases and sentences in red color. Make sure you understand them.
  2. Start biterScripting. Enter the following command exactly as you see it below. Then press the ENTER key.

    Command
    script "http://www.biterscripting.com/LearningScripting/Prep4.txt"


    Keep biterScripting open throughout this lesson. Make C:/LearningScripting/Lesson4 the current directory, by entering the following command. (This directory was created by the above script command.)

    Command
    ccd "C:/LearningScripting/Lesson4"




  3. Open the system viewer. Go to directory C:/LearningScripting/Lesson4. We will use this directory throughout this lesson.




QUESTION 4.1 What is a while loop ? Answer



QUESTION 4.2 What does the lex command do ? Answer





4.1. FILE DIRECTORY LOOP

You often have to process multiple files and/or directories on your computer in the same way. For example, you may wish to view files. Or, you may wish to edit a multitude of files in the exact same manner. Without scripting, you would have to do this manually - open each file, process it, save and close it. This could take a significant amount of your time. biterScripting provides a way to automate this, using the file directory loop.

The file directory loop is a scripting technique to loop through files and directories. The file loop is implemented using the following.

  • A string variable to hold a list of files and/or directories
  • The lf command to collect the list of files and/or directories
  • A while loop to process files and/or directories one by one
  • A lex command to get the next file or directory from the list


The following is the skeleton of the file loop.

Script filedirloop.txt
var string list
lf -rn "*.txt" "C:/LearningScripting" > $list
while ($list <> "")
do
    var string filedir
    lex "1" $list > $filedir
done


The first var command declares $list - the variable that will hold the list of files. The lf command collects a list of text files in directory C:/LearningScripting and places the list in $list. The while command loops through the list of files. The while condition is ($list <> ""). The <> operator means not equal to. (We will see all comparison operators in detail soon.)

Inside the do-done command block, the var command declares $filedir - the variable that will hold one file or directory name each time around the loop. The lex command extracts the next file or directory from the list one by one, and assigns it to the variable $filedir.

We learned the lf command earlier. If its stream output is not redirected, it would write its output to the screen. The output would contain one file/directory per line. That is exactly the way variable $list stores the output of the lf command - one file/directory per line.

Inside the while loop, the lex command extracts the first line from variable $list each time. The lex command also removes the first line from input each time, so next time around the while loop, the lex command will get the next line from variable $list - this is the essence of the file directory loop.

The above script only the skeleton script - it does not actually do anything with the files in the file list. We will use this skeleton as the basis of the scripts we will write soon.

QUESTION 4.3 Do you remember how to create a new script file ? We learned that in the last lesson. Go ahead and create a script file called filedirloop.txt in directory C:/LearningScripting/Lesson4. Copy and paste the above commands in that file. Answer

I will now show you the effectiveness of the file directory loop by creating some scripts that will actually do something with the files in the file directory loop. The first script will show contents of all text files. If you remember, the repro command reproduces the contents of a file. So, we will add a repro command within the do-done command block. The command argument to the repro command is file name. We have the file name in variable $filedir. So, we will use $filedir as the command argument for the repro command. Our resulting script will look like the following. Create the script reprofiles.txt, in directory C:/LearningScripting/Lesson4, with the following commands.

Script reprofiles.txt
var string list
lf -rn "*.txt" "C:/LearningScripting" > $list
while ($list <> "")
do
    var string filedir
    lex "1" $list > $filedir
    repro $filedir
done


Once the script reprofiles.txt is created, call the script by entering the following commands in biterscripting.

Commands
cd "C:/LearningScripting/Lesson4"
script "reprofiles.txt"


You should see contents of all text files within directory C:/LearningScripting in the output.

QUESTION 4.4 Create a new script reprofiles2.txt in directory C:/LearningScripting/Lesson4. Copy and paste the script reprofiles.txt into it. Change the reprofiles2.txt script in such a way that its output will show, for each file, the file name, then file contents. Answer





4.2. OPERATORS

In the last lesson, we learned about the while loop. It used a while condition. Earlier in this lesson, we learned about the file loop. Both of them were based on the while command which used a while condition. Many biterScripting commands use conditions. A condition is an expression that results in true or false. When the result is true, the condition is met. When the result is false, the condition is NOT met. A comparison operator is used to create a condition. I will list comparison operators below.

Comparison Operators
Operator NameOperator SymbolWhat must happen, for the condition to be true ?
less than<The item before the operator must be less than the item after the operator.
greater than>The item before the operator must be greater than the item after the operator.
equal to==The item before the operator must be equal to the item after the operator.
less than or equal to<=The item before the operator must be less than OR equal to the item after the operator.
greater than or equal to>=The item before the operator must be greater than OR equal to the item after the operator.
not equal to<>The item before the operator must NOT be equal to the item after the operator.




QUESTION 4.5 For each of the following conditions, is it true or false ?
  1. ( 3 < 5 )
  2. ( 3 == 5 )
  3. ( "a" == "a" )
  4. ( "a" == "b" )
  5. ( "a" < "b" )
  6. ( "a" <= "b" )
  7. ( "a" < "ab" )
Answer

Note that I used parentheses around each condition. biterScripting does not require it, but I think it is always a good idea to enclose individual conditions in parentheses.

In addition to comparison operators, biterscripting supports logical operators. A logical operator is an operator that combines two or more conditions. I will list the logical operators below.

Logical Operators
Operator NameOperator SymbolWhat must happen, for the condition to be true ?
ANDANDBoth the condition before the operator, AND the condition after the operator, must be true.
OROREither the condition before the operator, OR the condition after the operator, OR both conditions, must be true.
NOTNOTThe condition after the operator must NOT be true.




QUESTION 4.6 For each of the following conditions, is it true or false ?
  1. ( ( 3 < 5 ) AND ( "a" == "a" ) )
  2. ( ( 3 == 5 ) AND ( "a" == "a" ) )
  3. ( ( 3 == 5 ) OR ( "a" == "a" ) )
  4. ( NOT ( 3 < 5 ) )
Answer

Note again that I made generous use of parentheses when writing the conditions, a practice I highly recommend.



4.3. The AF COMMAND

The af command (access file) shows information about one file or directory. Enter the following command.

Command
af "sample4.txt"


The command's output contains various attributes about file sample4.txt. (This output is very similar to the lf command.) The first field is the size in bytes. The second field is the type (f means file, d means directory). Third field is the latest modification time. Fourth field is the latest access time. Fifth field is the creation time. The last field is the file or directory name itself. The af command has options that you can use to customize what attributes you want to see in the output.

QUESTION 4.7 Take a look at the help page for the af command. What option tells the af command to list only the file or directory name ? Answer

The af command lists various times associated with a file or a directory in a particular format. This is called the time format. The time format is the format in which all biterScripting commands list time. This format is represented as yyyymmddhhMMss . Let me explain each of the fields in the time format.

yyyyFour digit year. Example: 2007
mmTwo digit month. From 01 (January) through 12 (December).
ddTwo digit day. From 01 through 31.
hhTwo digit hour. This hour is on a 24-hour scale and ranges from 00 through 23.
MMTwo digit minutes. From 00 through 59.
ssTwo digit seconds. From 00 through 59.


For example, 20070218135032 would mean February 18, 2007, 1:50:32 PM.

Another important thing the af command does is the fact that it sets some system variables. System variables are the variables that are defined by the system for you. Any time you start biterScripting, these variables are already available to you. See the help page for the topic systemvar for a complete list of system variables. The af command sets some system variables associated with the specidied file or directory. These are -

fnamestring variable. Set to name of the file or directory.
ftypestring variable. Set to file type (f for file, d for directory).
fatimestring variable. Set to last access time of the file or directory.
fctimestring variable. Set to creation time of the file or directory.
fmtimestring variable. Set to last modification time of the file or directory.
fsizeinteger variable. Set to the size in bytes of the file. (For a directory, this is set to 0.)




As we saw, the af command works with directories also. Enter the following command.

Command
af "C:/LearningScripting"


The above command lists all attributes of the directory C:/LearningScripting.



4.4. IF-ELSE-ENDIF

We will learn about conditional execution of commands in this section. It is done using the if command. Create a script called if.txt in directory C:/LearningScripting/Lesson4 with the following commands.

Script if.txt
var integer number
set $number = 5
if ($number < 10)
do
    echo $number " is less than 10."
done
endif


Let me now explain the if.txt script we created command-by-command. The var command declared an integer variable - number.

The if command provides a mechanism to execute something if some condition is true. That condition is called the if condition. In our case the if condition is ($number < 10).

The if command is followed by a command block, which is created using the do and done commands. Our command block has one command, the echo command.

The overall syntax of the if command includes the if command, followed by the do command, followed by a number of commands, followed by a done command, ending in an endif command. The endif command marks the end of the conditional execution started by the if command .

Go ahead and execute the script. Enter the following command in the input area of biterScripting.

Command
script "if.txt"


The script prints "5 is less than 10.", as expected. (We assigned $number value of 5, therefore, it would be less than 10.) Thus, we verified that if the if condition is true, the command is executed. Now, let's verify the reverse. If the if condition is NOT true, would the echo command be executed ? To check, create a script if2.txt in directory C:/LearningScripting/Lesson4 by copying script if.txt. We will make only one change in this if2.txt script, by setting the value of $number to a number NOT less than 10. In the if2.txt script, change the set command to assign 15 to variable $number. The resulting if2.txt script will look like the following.

Script if2.txt
var integer number
set $number = 15
if ($number < 10)
do
    echo $number " is less than 10."
done
endif




Execute the script if2.txt. Enter the following command in the input area of biterScripting.

Command
script "if2.txt"


As expected, nothing was printed. (The echo command was NOT executed, because the if condition was NOT true.) What if we want to execute something if the if command is NOT true ? The else command is provided for that. The else command provides a mechanism to execute something if the if condition is NOT true. Create a script called ifelse.txt in directory C:/LearningScripting/Lesson4 with the following commands.

Script ifelse.txt
var integer number
set $number = 15
if ($number < 10)
do
    echo $number " is less than 10."
done
else
do
    echo $number " is NOT less than 10."
done
endif


Execute the script ifelse.txt. Enter the following command in the input area of biterScripting.

Command
script "ifelse.txt"


The script will print "15 is NOT less than 10."

You can use the while, if, script commands nested within one another, as below. Create the whileif.txt script with the following commands. (Create all these scripts in this lesson in the same directory - C:/LearningScripting/Lesson4 .)

Script whileif.txt
var integer number
while ($number <= 20)
do
    if ($number < 10)
    do
        echo $number " is less than 10."
    done
    else
    do
        echo $number " is NOT less than 10."
    done
    endif
    set $number=$number+1
done


Execute the script whileif.txt. Enter the following command in the input area of biterScripting.

Command
script "whileif.txt"


The output will be as expected. The script will print either "less than 10" or "NOT less than 10" for each integer from 0 to 20.

Some of the if-else-endif scripts I presented may seem a little ridiculous, but bear with me - we are going some place with them.



4.5. ARGUMENT PASSING - FVA

Copy the script ifelse.txt we created above to a new script file FVA.txt in directory C:/LearningScripting/Lesson4. Edit script file FVA.txt. Remove the line that set the value of $number to 15. The resulting FVA.txt script will look like the following.

Script FVA.txt
var integer number
if ($number < 10)
do
    echo $number " is less than 10."
done
else
do
    echo $number " is NOT less than 10."
done
endif


Now, execute the script with the following command.

Command
script "FVA.txt" number(15)


The output should be "15 is NOT less than 10.". Variable $number is declared inside the script FVA.txt, but we passed its value from outside when calling the script. This is the essence of FVA - Forward Variable Assignment.

FVA - Forward Variable Assignment is a mechanism used to pass arguments to a script. Using this mechanism, a variable declared within a script is assigned a value when calling the script. The syntax includes the variable name, followed by a value enclosed in parentheses.

Create a new script FVA2.txt in directory C:/LearningScripting/Lesson4 with the following commands.

Script FVA2.txt
var integer number2
while ($number2 <= 20)
do
    script "FVA.txt" number($number2)
    set $number2=$number2+1
done




Above, we have a while loop which takes $number2 from 0 thru 20. Each time within the while loop, we call script FVA.txt and pass it the then current value of $number2. Execute the script with the following command.

Command
script "FVA2.txt"


The result is as can be predicted. The output shows, for each integer between 0 and 20, if the integer is, or is NOT, less than 10.

We will now put all the information we learned today into one script - a script that finds the file, or directory that was created the latest. We will call this script - latest.txt.

This script will take one input argument - the name or path of the directory within which we will search for files and directories. We will call this argument topdir (top directory). Its variable type will be string.

We will start the script by declaring the input argument - topdir. The caller to the script will pass the value of $topdir using FVA. The value will be the name or path of a directory where the script will begin its search. Create the script latest.txt in directory C:/LearningScripting/Lesson4, with the following commands.

Script latest.txt
##################################################################
# SCRIPT latest.txt
##################################################################
# This script finds the latest created file or directory within a top directory.
# The caller should pass the top directory to this script by assigning value to
# variable topdir, using FVA, such as following.
#
# script latest.txt topdir("C:/LearningScripting")
#
##################################################################

# Input argument topdir - the directory where the search will begin
var string topdir




We will build this script together step-by-step. I will list the script after each step. I will show the newly added commands (and comments) in the blue color. Please edit the script step-by-step as we go along. Save the script file after each step, but keep the file open. We will now include a file directory loop into this script, as follows.

Script latest.txt
##################################################################
# SCRIPT latest.txt
##################################################################
# This script finds the latest created file or directory within a top directory.
# The caller should pass the top directory to this script by assigning value to
# variable topdir, using FVA, such as following.
#
# script latest.txt topdir("C:/LearningScripting")
#
##################################################################

# Input argument topdir - the directory where the search will begin
var string topdir

# The following variable stores the list of files and directories.
var string list
# Collect a list of all files and directories within $topdir .
lf -rn "*" $topdir > $list
while ($list <> "")
do
    # Get the next file or directory.
    var string filedir
    lex "1" $list > $filedir
done


We are collecting the list of files and directories in variable $list. We are getting one file or directory at a time into variable $filedir. We will keep the latest created file or directory in string variable $latestfiledir. And, we will kepp the latest creation time found so far, in a string variable $latesttime.

Script latest.txt
##################################################################
# SCRIPT latest.txt
##################################################################
# This script finds the latest created file or directory within a top directory.
# The caller should pass the top directory to this script by assigning value to
# variable topdir, using FVA, such as following.
#
# script latest.txt topdir("C:/LearningScripting")
#
##################################################################

# Input argument topdir - the directory where the search will begin
var string topdir

# The following variable stores the list of files and directories.
var string list
# Collect a list of all files and directories within $topdir .
lf -rn "*" $topdir > $list

# We will store the file or the directory that was created latest, in the following variable.
var str latestfiledir
# We will store the latest creation time in the following variable.
var str latesttime


while ($list <> "")
do
    # Get the next file or directory.
    var string filedir
    lex "1" $list > $filedir
done


The nextt thing we have to do is to keep correcting the $latesttime and $latestfiledir as we go thru $list. If the file or directory we are currently processing, has its creation time later than $latesttime, we will assign that file or directory to $latestfiledir. Similarly, we will assign that file or directory's creation time to $latesttime. We will use the af command to get each file or directory's creation time. If you remember, the af command saves the creation time for a file or directory into system variable $fctime.

Script latest.txt
##################################################################
# SCRIPT latest.txt
##################################################################
# This script finds the latest created file or directory within a top directory.
# The caller should pass the top directory to this script by assigning value to
# variable topdir, using FVA, such as following.
#
# script latest.txt topdir("C:/LearningScripting")
#
##################################################################

# Input argument topdir - the directory where the search will begin
var string topdir

# The following variable stores the list of files and directories.
var string list
# Collect a list of all files and directories within $topdir .
lf -rn "*" $topdir > $list

# We will store the file or the directory that was created latest, in the following variable.
var str latestfiledir
# We will store the latest creation time in the following variable.
var str latesttime

while ($list <> "")
do
    # Get the next file or directory.
    var string filedir
    lex "1" $list > $filedir

    # Get this file or directory's creation time using the af command.
    af $filedir
    # The af command has set this file or directory's creation time into $fctime.
    # Is $fctime greater than $latesttime ?
    if ($fctime > $latesttime)
    do
        # Yes, this $filedir was created later than $latesttime.
        # Reassign $latesttime and $latestfiledir.
        set $latesttime = $fctime
        set $latestfiledir = $filedir
    done
    endif

done


When we come out of the file directory loop, the file or directory that was created latest is in $latestfiledir. Its creation time is in $latesttime. The final step is to show these two items to the user.

Script latest.txt
##################################################################
# SCRIPT latest.txt
##################################################################
# This script finds the latest created file or directory within a top directory.
# The caller should pass the top directory to this script by assigning value to
# variable topdir, using FVA, such as following.
#
# script latest.txt topdir("C:/LearningScripting")
#
##################################################################

# Input argument topdir - the directory where the search will begin
var string topdir

# The following variable stores the list of files and directories.
var string list
# Collect a list of all files and directories within $topdir .
lf -rn "*" $topdir > $list

# We will store the file or the directory that was created latest, in the following variable.
var str latestfiledir
# We will store the latest creation time in the following variable.
var str latesttime

while ($list <> "")
do
    # Get the next file or directory.
    var string filedir
    lex "1" $list > $filedir

    # Get this file or directory's creation time using the af command.
    af $filedir
    # The af command has set this file or directory's creation time into $fctime.
    # Is $fctime greater than $latesttime ?
    if ($fctime > $latesttime)
    do
        # Yes, this $filedir was created later than $latesttime.
        # Reassign $latesttime and $latestfiledir.
        set $latesttime = $fctime
        set $latestfiledir = $filedir
    done
    endif

done

# Show the user the lastest created file or directory, and its creation time.
echo "The file or directory created the latest is " $latestfiledir "."
echo "Its creation time was " $latesttime "."


That's it. Save the final version of the script. And run it as follows.

Command
script "latest.txt" topdir("C:/LearningScripting")


The above will show you the file or directory within C:/LearningScripting that was created latest, and that latest creation time. You can now run this script with any value for $topdir, such as "C:/Program Files".

(If you use a top directory maintained by your operating system, the operating system will slow this script down significantly. That is because the operating system itself is searching and modifying in those directories constantly.)

One last thing to do - when you executed the script, you saw a full listing of each file or directory being processed. That was the output of the af command. To suppress that output, let's redirect the stream output of the af command, as follows.

Script latest.txt
##################################################################
# SCRIPT latest.txt
##################################################################
# This script finds the latest created file or directory within a top directory.
# The caller should pass the top directory to this script by assigning value to
# variable topdir, using FVA, such as following.
#
# script latest.txt topdir("C:/LearningScripting")
#
##################################################################

# Input argument topdir - the directory where the search will begin
var string topdir

# The following variable stores the list of files and directories.
var string list
# Collect a list of all files and directories within $topdir .
lf -rn "*" $topdir > $list

# We will store the file or the directory that was created latest, in the following variable.
var str latestfiledir
# We will store the latest creation time in the following variable.
var str latesttime

while ($list <> "")
do
    # Get the next file or directory.
    var string filedir
    lex "1" $list > $filedir

    # Get this file or directory's creation time using the af command.
    af $filedir > null
    # The af command has set this file or directory's creation time into $fctime.
    # Is $fctime greater than $latesttime ?
    if ($fctime > $latesttime)
    do
        # Yes, this $filedir was created later than $latesttime.
        # Reassign $latesttime and $latestfiledir.
        set $latesttime = $fctime
        set $latestfiledir = $filedir
    done
    endif

done

# Show the user the lastest created file or directory, and its creation time.
echo "The file or directory created the latest is " $latestfiledir "."
echo "Its creation time was " $latesttime "."


Notice that we redirected the stream output of the af command to 'null'. null is a special redirection target, which suppresses the input or output. Run the script again. You will see the result.



DID YOU KNOW ?
  1. If you want to execute only one command when an if condition is true, you do not need the do and done commands around that command. In other words, you do not need to create a command block for a single command. For example, in our if.txt script, we could have written that script without the do-done commands, as follows.

    Script if.txt - without do-done command block
    var integer number
    set $number = 5
    if ($number < 10)
        echo $number " is less than 5."
    endif


    This is true for commands following the if command, the else command, or the while command. If it is a single command, you do not need to create a do-done command block for just one command.

    Although biterScripting allows this, I recommend using the do-done command block after each if, else and while command. It just makes good programming practice.

  2. We have been using the echo command a lot. We know that it writes to stream output. The option -e can be used with the echo command to make it write to stream error instead. This comes in very handy when inserting debug messages into a script. A debug message is a message written out to stream error that indicates progress of a script. Debug messages are written using the -e option of the echo command.

    Open the script whileif.txt for editing. Insert the echo command shown below in blue color into that script.

    Script whileif.txt
    var integer number
    while ($number <= 20)
    do
        echo -e "DEBUG: The value of variable $number is " $number "."

        if ($number < 10)
        do
            echo $number " is less than 10."
        done
        else
        do
            echo $number " is NOT less than 10."
        done
        endif
        set $number=$number+1
    done


    Execute the script whileif.txt by entering the following command.

    Command
    script "whileif.txt"


    The output shows you all the debug messages. To suppress the debug messages, simply redirect stream error of the script command to null, as follows.

    Command
    script "whileif.txt" 2 > null








SUMMARY
In this lesson, we learned
  1. How to create a file directory loop.
  2. About various operators.
  3. The af command.
  4. How to implement if-else-endif commands.
  5. FVA - Forward Variable Assignment.




HOMEWORK 4
  1. Revisit the important concepts we learned in this lesson. (Look at this page from top to bottom. The important concepts are the words, phrases or sentences in red color.) Did you understand them ? Answer
  2. We created a script called latest.txt, which listed the latest created file or directory and the latest creation time. Create a script called lastestmod.txt based on latest.txt. Change the script latestmod.txt so that, it will list the LATEST MODIFIED file or directory and the LATEST MODIFICATION TIME. Answer





© 2008-2014, biterScripting.com. All rights reserved.
biterScripting, biterScript, biterBrowser, biterMobile, biterScripting.com, FVA (Forward Variable Assignment) are trademarks of biterScripting.com. Is it biterScripting-compatible ? is a service mark of biterScripting.com. Explorer, Unix, Windows are trademarks, service marks or other forms of intellectual property of their respective owners.