PRODUCT |

|

|
|

|
|
|
|
|
FAQ |
|

|
|
|
|
|
|
LEARN SCRIPTING |
|

|
|
|
|
|
|
|
|
|
|
SAMPLE SCRIPTS |
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
HELP / DOCUMENTATION |
|

|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
Learning Scripting - Lesson 5
(system command, sen command, File Search, Script development techniques)
|
|
In this lesson, we will learn a couple of new commands - system and sen. We will implement the
file search mechanism using the sen command. We will look at some
of the script development techniques. As part of the discussion, we will develop a script to search
emails on a computer.
PREPARATION
-
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.
-
Start biterScripting. Enter the following command exactly as you see it below. Then press the ENTER key.
Command
script "http://www.biterscripting.com/LearningScripting/Prep5.txt"
Keep biterScripting open throughout this lesson. Make
C:/LearningScripting/Lesson5 the current directory, by entering the following command.
(This directory was created by the above script command.)
Command
ccd "C:/LearningScripting/Lesson5"
-
Open the system viewer. Go to directory C:/LearningScripting/Lesson5. We will use this
directory throughout this lesson.
5.1. SYSTEM COMMAND
The system command automates mouse clicking and keyboard typing. Some examples
of automation:
- Double clicking on a file to open that file
- Double clicking on an executable to start a program
- Moving a file by dragging and dropping it
- Making a copy of a file using CTRL-C and CTRL-V
- Renaming a directory by right clicking on it
I will demonstrate. Go to your system viewer. Go to directory C:/LearningScripting/Lesson5.
Double click on file Sample5.txt. The file is opened in a text editor. Close the text editor (and the file).
Now, enter the following commands in biterScripting input area.
Commands
ccd "C:/LearningScripting/Lesson5"
system "sample5.txt"
The file sample5.txt was opened in a text editor. The system command simulated the double-click behavior.
Go ahead and close the text editor (and the file). Now, let's try something else. In the system viewer, go to
directory C:/LearningScripting/Lesson5. Drag and drop file Sample5.txt from directory C:/LearningScripting/Lesson5
to directory C:/LearningScripting/Lesson4. This moves the file from one directory to another. Now, we will
move this file back using the system command. Enter the following command.
Commands
ccd "C:/LearningScripting/Lesson5"
system move "C:/LearningScripting/Lesson4/sample5.txt" "C:/LearningScripting/Lesson5"
Check in the system viewer. You will see that file sample5.txt is back in directory C:/LearningScripting/Lesson5.
I will now list some of the common usages of the system command.
The system commands for files
Command | Type of behavior | Description of the behavior |
system file_name_with_extension_.exe | Double clicking on an executable or a program. | That executable or the program is started. |
system file_name_with_extension_other_than_.exe | Double clicking on a file that is not an executable. | That file is opened with the default program associated with that extension. For example, a .txt file will be opened in a text editor. |
system copy file1 file2 | Copying and pasting a file. | file1 will be copied as file2. |
system copy file1 directory2 | Copying a file, then pasting it into a directory. | file1 will be copied to directory2. It will have the same file name. |
system rename file1 file2 | Right clicking a file, then renaming it. | file1 will be renamed file2. |
system move file1 directory2 | Dragging and dropping a file from one directory to another. | file1 will be moved to directory2. It will have the same name. |
system delete file1 | Clicking on a file, then pressing the delete key. | file1 will be deleted. |
The system commands for directories
system mkdir directory1 | Right clicking within a directory, then selecting new. | A new directory will be created. Its name will be directory1. |
system rmdir directory1 | Selecting a directory, then pressing the delete key. | The directory1 will be deleted if it is empty. (Yes, there is a command to delete a directory even if it is not empty. But, that activity is best done manually and not automated in a script.) |
There are commands that do other things with directories - rename, copy, move, etc. But I recommend that you
do those things manually upon some reflection. So, I would rather not tell you about those commands.
The system command waits until the operating system completes the tasks it was assigned by the system command.
QUESTION 5.1
Write commands that will make a new directory C:/LearningScripting/Lesson5/test, then
copy file C:/LearningScripting/Lesson5/Sample5.txt to that newly created directory.
Answer
QUESTION 5.2
Create a script file copyall.txt in directory C:/LearningScripting/Lesson5 that will create a new
directory C:/LearningScripting/Lesson5/test2, the copy
all .txt files in directory C:/LearningScripting (and its subdirectories)
to that directory.
Answer
5.2. SEN COMMAND
We looked at the lex (line extractor) command earlier, which was part of a class of commands
known as Automated Editors. Another useful command in this class is the sen command.
The sen command (string enumerator or counter) counts instances of a string
in an input string. In other words, it counts how many times a specified string appears inside an
input string. The string whose instances are being counted is called
the search string .
The syntax of this command includes the sen command followed by a string followed by the input string.
Enter the following command.
Command
sen "^bcd^" "abcdefghijklmnopqrstuvwxyz"
The above command counts how many times the string "bcd" appears inside of the input string. The input string
is "abcdefghijklmnopqrstuvwxyz". The search string is "bcd". The command's output is 1. That means
there is 1 instance of string "bcd" inside the input string. In other words, the search string "bcd" appears
one time inside the input string.
It is important to note that the search string is enclosed within symbols ^ . This symbol is called
a caret.
QUESTION 5.3
How many times does the search string "bcd" appear inside the input string "b cd bcd bbcd bd bc" ?
Answer
The search string and the input string can both be passed using string variables. That's where the
power of sen (and other automated editor commands) comes in. Enter the following commands.
Commands
var string content
cat "C:/LearningScripting/Lesson5/Sample5.txt" > $content
sen "^Rome^" $content
The output is 1, since the search string "Rome" appears once inside the content of file Sample5.txt.
Verify this by viewing the file Sample5.txt from system viewer, by double clicking on it. Also, check in
that file, that there is a word "dallas" - it is all in lower case lettters. How can we search for
a string inside the contents of a file irrespective of the case ? This is accomplished using the
-c option of the sen command. The -c option directs the sen command to do a case-independent or
case-insensitive search. Enter the following commands.
Commands
cat "C:/LearningScripting/Lesson5/Sample5.txt" > $content
sen "^Dallas^" $content
sen -c "^Dallas^" $content
The first sen command will return 0, since it does not have the -c option, and without the -c option,
"dallas" does not match "Dallas". The second sen command returns 1, since it has the -c option. With
the -c option, "dallas", "Dallas", "DALLAS", "daLAas" will all match the search string "Dallas".
We can redirect the stream output from the sen command to a string variable. We can then check the
value of that string variable. If it is "0", our search string is not present in the file. If it is
anything else, the search string is present in the file.
We have just discovered a trick to check if a search string appears inside a file using the
sen command. It is called the File Search mechanism. We will elaboreate on it in the next section.
QUESTION 5.4
Read the help page for the sen command. What do you need to do if the search string itself contains
a caret (^), such as, if "a^b" is the search string ?
Answer
5.3. FILE SEARCH
File Search is a mechanism to check if
a string is present inside a file. It is implemented by reading a file into a string
variable, then using the sen command on that variable. The string to search for, is called, again, the
search string. Let's create a script for the file search mechanism.
Create the following script filesearch.txt in directory C:/LearningScripting/Lesson5.
Script filesearch.txt
##################################################################
# SCRIPT filesearch.txt
##################################################################
# This script checks if a particular search string is present inside a file.
##################################################################
# We will read the contents of the file into the following string variable.
var string content
# Read the contents of the file into $content.
repro "C:/LearningScripting/Lesson5/Sample5.txt" > $content
# We will use the sen command to check if the search string is present
# in $content. We will use the -c option to do a case-independent search.
# We will redirect the output of the sen command to the following string variable.
var string output
sen -c "^Dallas^" $content > $output
# If $output is "0", the search string is not present. If $output is
# anything else, the search string is present.
if ($output <> "0")
do
# Search string is present.
echo "Search string is present."
done
endif
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.
Let's make this filesearch.txt script more general. Currently, the file to search is hard-coded
as "C:/LearningScripting/Lesson5/Sample5.txt". Let's pass the file as an argument to this script.
Script filesearch.txt
##################################################################
# SCRIPT filesearch.txt
##################################################################
# This script checks if a particular search string is present inside a file.
#
# The input argument file is the file to search in.
#
# The caller should call this script as following.
#
# script filesearch.txt file("C:/LearningScripting/Lesson5/Sample5.txt")
##################################################################
# Input argument file - the file to search in.
var string file
# We will read the contents of the file into the following string variable.
var string content
# Read the contents of the file into $content.
repro $file > $content
# We will use the sen command to check if the search string is present
# in $content. We will use the -c option to do a case-independent search.
# We will redirect the output of the sen command to the following string variable.
var string output
sen -c "^Dallas^" $content > $output
# If $output is "0", the search string is not present. If $output is
# anything else, the search string is present.
if ($output <> "0")
do
# Search string is present.
echo "Search string is present."
done
endif
Next thing, instead of searching for a fixed (hard-coded) string "Dallas", we will pass
the search string also as an input argument. We will declare a string variable
called search_string, and pass its value using FVA - Forward Variable Assignment.
There is a bit of a problem here. The caller to our script will pass us the search_string
as "Dallas". We need to enclose
it in carets (^) before using it in the sen command. To do that, we will declare a
string variable called sen_argument, assign its value as a caret, followed by $search string,
followed by another caret. We will then use the variable
$sen_argument in the sen command. (This is a
rather useful trick - so make sure you understand the code that does this trick.)
Script filesearch.txt
##################################################################
# SCRIPT filesearch.txt
##################################################################
# This script checks if a particular search string is present inside a file.
#
# The input argument file is the file to search in.
#
# The input argument search_string is the string to search for.
#
# The caller should call this script as following.
#
# script filesearch.txt file("C:/LearningScripting/Lesson5/Sample5.txt") search_string("Dallas")
##################################################################
# Input argument file - the file to search in.
var string file
# Input argument search_string - the string to search for.
var string search_string
# We will read the contents of the file into the following string variable.
var string content
# Read the contents of the file into $content.
repro $file > $content
# We will create the argument for the sen command in a separate string variable.
# It will have the value of caret (^), followed by the value of $search_string,
# followed by the closing caret.
var string sen_argument
set $sen_argument = "^" + $search_string + "^"
# We will use the sen command to check if the search string is present
# in $content. We will use the -c option to do a case-independent search.
# We will redirect the output of the sen command to the following string variable.
var string output
sen -c $sen_argument $content > $output
# If $output is "0", the search string is not present. If $output is
# anything else, the search string is present.
if ($output <> "0")
do
# Search string is present.
echo "Search string is present."
done
endif
That's it. Execute the script with the following command.
Command
script "C:/LearningScripting/Lesson5/filesearch.txt" file("C:/LearningScripting/Lesson5/Sample5.txt") search_string("Dallas")
You can now use this script to search any file on your computer for any search string.
You may not have yet realized the power of this script. We saw earlier that biterScripting does NOT make
a distinction between local files and web pages. That means we can use our filesearch.txt script to
search not only the local files, but also web pages on any web site. I will demonstrate with the
next question.
QUESTION 5.5
Does the web page at http://www.biterscripting.com contain the word "now" ? Does it contain the word
"later" ?
Answer
We will use the power of the script filesearch.txt in the next section,
where we will build a script to perform searches on emails on a computer.
(Have you evern lost email addresses of old friends ? This script may be for you.)
5.4. SCRIPT DEVELOPMENT TECHNIQUES
In this section, we will see learn some of the commonly used script development techniques.
As part of the discussion, we will develop a new script emailsearch.txt that will search
emails on your computer for a specific search string.
Take a look at your email program. Find out in which directory it stores emails on your computer.
This is called the email storage directory.
(Many operating systems use the term 'folder' instead of directory. Similarly, some email programs
use the term 'storage folder' for the directory where they store emails.)
Emails are stored in files in that directory and its subdirectories. Each file contains
one email. These files are called email files.
Find out what extension your email program uses for email files.
For example, if you use Outlook Express (Outlook Express is a trademark, service mark, or other
forms of intellectual property of its respective owner.), you can go in
Tools->Options->Advanced->Maintenance->Store Folder
to find out the email storage directory. Also, the extension for email files is .eml.
Since I don't know your specific email storage directory and the extension of email files,
I will use an example for each of them.
- Email storage directory - we will use C:/LearningScripting/Lesson5 .
- Extension for email files - we will use .eml .
We will now begin to develop the script. I will write each script development technique
in red color, then explain it, then follow it up with our example script - emailsearch.txt.
-
Don't just write a script, tell a story !
Use comments generously throughout a script.
Tell the readers what the script does, how it does it, what each
variable does. Tell the readers what command options you are using to make a command behave
a certain way. Tell them about any special tricks you are using. Show them examples of
how the script is to be invoked. Write comments that cover
all of these. There are several benefits of having generous comments within a script.
-
If you don't use a script for a while, then need to start using it again, you will
quickly understand what the script is doing and how.
-
If you need to change a script based on changed requirements, you will quickly
know what changes are needed and where to put them in.
-
When you need to write a brand-new script, you can look at other scripts you have
developed, and quickly figure out which ones you can reuse for your brand-new requirements.
-
If you share scripts that you have developed with others, other users of your scripts
can quickly understand what the script does and how it is doing it.
-
Document requirements well.
Script requirements are documented using description of what the script does.
Using comments at the top of the script, tell the reader what the script does.
Make these documented requirements as descriptive and as explicit as possible.
Mention any gotchas and exceptions that the script does not handle.
We will start developing our emailsearch.txt script by first documenting requirements.
Create a new script file emailsearch.txt in directory C:/LearningScripting/Lesson5 with
the following code.
Script emailsearch.txt
##################################################################
# SCRIPT emailsearech.txt
##################################################################
# This script searches email files on a local computer based on
# a search string. The script lists the email file name and the
# contents of the email file, for each email file that contains
# the search string.
##################################################################
As before, we will develop this script in steps. I will show the new code and comments
added or changed within each step in blue color. Save the script file
after each step, but keep the file open for for further editing.
-
Define input arguments.
Input arguments to a script are passed using FVA - Forward Variable Assignment.
Define input arguments before you begin to write a script.
Document them with comments at the top of the script. Tell the reader how these
input arguments are to be assigned with examples. Tell the reader what default
values will be used if these input arguments are not assigned.
The first part of the script code should include declarations of the input
arguments using the var command. This part of the code should also include
checking if input arguments are assigned, and if not, assigning them default
values.
Script emailsearch.txt
##################################################################
# SCRIPT emailsearech.txt
##################################################################
# This script searches email files on a local computer based on
# a search string. The script lists the email file name and the
# contents of the email file, for each email file that contains
# the search string.
#
# The script accepts following input arguments.
#
# storagedir - directory where email files are stored. If not assigned,
# current directory will be used.
#
# files - a file pattern for email files. If not assigned,
# "*" will be used, which means all files will
# be treated as email files.
#
# search_string - the search string. Email files will be searched for
# this string. If not assigned, an empty search string will be
# used, which will return errors.
#
# Call this script as following.
#
# script "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
#
##################################################################
# Declare input arguments.
var string storagedir, files, search_string
# Is $storagedir assigned ? If not, assign current directory.
if ($storagedir == "")
scd > $storagedir
endif
# Is $files assigned ? If not, assign "*".
if ($files == "")
set $files = "*"
endif
# We don't need to check if $search_string is assigned. If not assigned, the script will return
# errors.
-
Use descriptive variable names.
Descriptive variable names instantly convey to the reader what those variables are for.
In our example script - emailsearch.txt, we could have called the input arguments x, y and z, instead of,
storagedir, files and search_string. But, x, y and z, don't really convey to the reader what these variables
are for. Variable names sd (for storagedir), f (for files) and ss (search_string) could also have been used.
They are a little better than x, y and z. But, still the reader would have to scratch his/her head a bit to
figure out what these variables are for. We chose the variable names storagedir, files and search_string because
they are fully descriptive.
-
Break up the functionality into small tasks.
Breaking up functionality of a script into small tasks, makes a complex problem simpler. In our example
script emailsearch.txt, we know that we need to do the following tasks.
-
Task 1 - Collect a list of email files that match the file pattern $files in directory $storagedir.
Loop thru these files one by one.
-
Task 2 - Check if the search string $search_string is present in an email file.
-
Task 3 - If the search string is present in an email file, print the file name, followed by the
contents of the file.
Having broken up our script into smaller tasks does make our script development much easier. (Some students
find it easier to do this task breakup in writing - that clarifies the tasks much better for them. The writing
can be done on a piece of paper or the write-up can just be included in the script itself as comments.
Other students prefer to do this task breakup in their head. I will leave it up to you to do the task
breakup using a method that you are most comfortable with.)
-
Reuse. Reuse. Reuse.
For each task within a script, think of a script or code that you have already developed.
Then reuse that code using copy-paste-edit approach as follows.
-
Copy relevant part of the script or code you have already developed.
-
Paste that part into the current script you are developing.
-
Edit that part to meet the requirements of the current script you are developing.
We identified three tasks above. We have already developed several scripts through these
lessons. Let's identify which ones we can reuse for each of our tasks identified above.
-
Task 1 - To collect a list of email files, then loop thru these files one by one
we can reuse the script filedirloop.txt. We created that script in Lesson 4, and stored
it in directory C:/LearningScripting/Lesson4. It is based on the technique called the
File Directory Loop.
-
Task 2 - To check if a search string is present in a file, we can reuse the script
filesearch.txt. We developed it in this lesson and stored it in directory
C:/LearningScripting/Lesson5. It is based on the File Search mechanism.
-
Task 3 - To print the file name, followed by the
contents of the file, we can reuse the script reprofiles2.txt. It is also based
on the File Directory Loop technique. We created that script in Lesson4 (in response
to Question 4.4) and stored in directory C:/LearningScripting/Lesson4.
There are several advantages to reusing. I will list a few.
-
Confidence - You know that you are reusing scripts and code that have
already been tested and are working correctly.
-
Speed - You can increase the speed of your script development. In a shorter
time, you can create a rich collection of scripts that automate a lot of things for you.
-
Modularity - Often times, instead of copy-paste-edit'ing a previous script into
the script you are currently developing, you can simply call that script from your current
script with the script command. This helps compartmentalize the script's functionality, as well
as shorten the sizes of your various scripts. A shorter script is more manageable.
You can consider reusing scripts from any of the following sources.
-
Scripts you have written.
-
Sample scripts provided as part of biterScripting and on biterscripting.com web site.
-
Scripts written by other people whom you know.
-
Several scripts are posted on various web sites. These scripts are written by various people.
They developed these scripts for their own requirements, then posted them for others who may
have similar requirements. (When reusing scripts from people you personally don't know - be
careful. Make sure you completely understand the script before you use it.)
-
Develop the script in steps.
Add the code for one task at a time. Test the script after each step. This allows you
to gradually debug and fix your script - one task in each step.
We will now go ahead, and add code for Task 1 in our script. We will reuse the code
from script filedirloop.txt in directory C:/LearningScripting/Lesson4. In our newly
learnt style of commenting generously, we will add comments to the reused code.
Script emailsearch.txt
##################################################################
# SCRIPT emailsearech.txt
##################################################################
# This script searches email files on a local computer based on
# a search string. The script lists the email file name and the
# contents of the email file, for each email file that contains
# the search string.
#
# The script accepts following input arguments.
#
# storagedir - directory where email files are stored. If not assigned,
# current directory will be used.
#
# files - a file pattern for email files. If not assigned,
# "*" will be used, which means all files will
# be treated as email files.
#
# search_string - the search string. Email files will be searched for
# this string. If not assigned, an empty search string will be
# used, which will return errors.
#
# Call this script as following.
#
# script "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
#
##################################################################
# Declare input arguments.
var string storagedir, files, search_string
# Is $storagedir assigned ? If not, assign current directory.
if ($storagedir == "")
scd > $storagedir
endif
# Is $files assigned ? If not, assign "*".
if ($files == "")
set $files = "*"
endif
# We don't need to check if $search_string is assigned. If not assigned, the script will return
# errors.
# Use the lf command to collect a list of email files. The first argument to the
# lf command is file pattern, we have that in $files. The second argument is
# the directory, we have that in $storagedir.
var string list
lf -rn $files $storagedir > $list
while ($list <> "")
do
# Get the next file into a string variable.
var string filedir
lex "1" $list > $filedir
# The next file is now in $filedir.
done
-
Use test data.
Until the script is completely developed, tested and debugged, and until you are satisfied that
it is working correctly, use small test data, instead of real data. In our case, we are developing
a script that searches emails. So, instead of trying the script out with your real emails at this
stage, it is best to copy a few of your email files into a test directory.
A few test email files are already downloaded into directory C:/LearningScripting/Lesson5.
This was done as part of the preparation for this lesson, when you executed the Prep5.txt
script. Type the following command to see the contents of these email files.
Command
repro "*.eml"
-
Use -p, -l options of the script command.
We are developing our emailsearch.txt script in steps. In each step, it is a recommended practice
to test the script with the -p and -l options of the script command. The -p option tells
biterScripting to only parse the script and not to execute it. If there are any syntax errors,
they will be checked with the -p option. The -l option tells biterScripting to
list command and comment lines in the script.
(Without the -l option, the script command does not list command
and comment lines.) If an error is present, it will be listed immediately below the command line
that is causing that error. The -p and -l options can be combined as -pl.
Go ahead and test our script so far with the following command.
Command
script -pl "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
If the word 'Ready' appears in the status area, there are no syntax errors.
-
Use debug statements.
We talked, in an earlier lesson, about inserting debug statements in a script, with
the -e option of the echo command. Let's put it to practice.
Insert the debug statements in the emailsearch.txt script as below.
Script emailsearch.txt
##################################################################
# SCRIPT emailsearech.txt
##################################################################
# This script searches email files on a local computer based on
# a search string. The script lists the email file name and the
# contents of the email file, for each email file that contains
# the search string.
#
# The script accepts following input arguments.
#
# storagedir - directory where email files are stored. If not assigned,
# current directory will be used.
#
# files - a file pattern for email files. If not assigned,
# "*" will be used, which means all files will
# be treated as email files.
#
# search_string - the search string. Email files will be searched for
# this string. If not assigned, an empty search string will be
# used, which will return errors.
#
# Call this script as following.
#
# script "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
#
##################################################################
# Declare input arguments.
var string storagedir, files, search_string
# Is $storagedir assigned ? If not, assign current directory.
if ($storagedir == "")
scd > $storagedir
endif
# Is $files assigned ? If not, assign "*".
if ($files == "")
set $files = "*"
endif
# We don't need to check if $search_string is assigned. If not assigned, the script will return
# errors.
echo -e "DEBUG: Looking for search_string " $search_string " in files " $files " in directory " $storagedir
# Use the lf command to collect a list of email files. The first argument to the
# lf command is file pattern, we have that in $files. The second argument is
# the directory, we have that in $storagedir.
var string list
lf -rn $files $storagedir > $list
while ($list <> "")
do
# Get the next file into a string variable.
var string filedir
lex "1" $list > $filedir
# The next file is now in $filedir.
echo -e "DEBUG: Processing file " $filedir
done
Let's execute our script, first with the -pl options, then without the -pl options.
Commands
script -pl "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
script "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
-
Keep the number of command lines in any one script small.
It makes a script more manageable if the number of command lines (not counting
comment lines and blank lines) within the script is small. Up to 50 command lines
is very good. Up to 100 command lines is ok. Anything more than 100 command lines
indicates some restructuring may be required - you may want to consider breaking that
script up into two or more scripts.
For example, we now need to add the code for Task 2 to our emailsearch script - code
that will check if the search string $search_string is present in an email file. We have already
developed a separate script for that - filesearch.txt. So, instead of copying the code for that
script into this script, why don't we simply call that script from this script, as follows ?
Script emailsearch.txt
##################################################################
# SCRIPT emailsearech.txt
##################################################################
# This script searches email files on a local computer based on
# a search string. The script lists the email file name and the
# contents of the email file, for each email file that contains
# the search string.
#
# The script accepts following input arguments.
#
# storagedir - directory where email files are stored. If not assigned,
# current directory will be used.
#
# files - a file pattern for email files. If not assigned,
# "*" will be used, which means all files will
# be treated as email files.
#
# search_string - the search string. Email files will be searched for
# this string. If not assigned, an empty search string will be
# used, which will return errors.
#
# Call this script as following.
#
# script "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
#
##################################################################
# Declare input arguments.
var string storagedir, files, search_string
# Is $storagedir assigned ? If not, assign current directory.
if ($storagedir == "")
scd > $storagedir
endif
# Is $files assigned ? If not, assign "*".
if ($files == "")
set $files = "*"
endif
# We don't need to check if $search_string is assigned. If not assigned, the script will return
# errors.
echo -e "DEBUG: Looking for search_string " $search_string " in files " $files " in directory " $storagedir
# Use the lf command to collect a list of email files. The first argument to the
# lf command is file pattern, we have that in $files. The second argument is
# the directory, we have that in $storagedir.
var string list
lf -rn $files $storagedir > $list
while ($list <> "")
do
# Get the next file into a string variable.
var string filedir
lex "1" $list > $filedir
# The next file is now in $filedir.
echo -e "DEBUG: Processing file " $filedir
# Is the $search_string present in file $filedir ?
var string output
script "filesearch.txt" file($filedir) search_string($search_string) > $output
if ($output == "Search string is present.")
do
# Search string is present. List file name and file contents.
done
endif
done
Let's take a look at the call to script filesearch.txt. One of its arguments is passed using
the syntax
search_string($search_string). The search_string outside the parentheses is
the input argument - it is a variable declared inside the script being called - filesearch.txt.
This is the variable whose value is being assigned.
The $search_string inside the parentheses is the value that is being assigned.
$search_string is a variable declared inside this script - emailsearch.txt.
They both happen to have the same name, and that's quite acceptable.
We will execute our script again, first with the -pl options, then without the -pl options.
Commands
script -pl "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
script "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
The last thing we want to do is to add the code for Task 3 - print the file name, followed by the
contents of the file. For that, we are going to reuse the script reprofiles2.txt in directory
C:/LearningScripting/Lesson4. Let's copy-paste-edit that code in as follows.
Script emailsearch.txt
##################################################################
# SCRIPT emailsearech.txt
##################################################################
# This script searches email files on a local computer based on
# a search string. The script lists the email file name and the
# contents of the email file, for each email file that contains
# the search string.
#
# The script accepts following input arguments.
#
# storagedir - directory where email files are stored. If not assigned,
# current directory will be used.
#
# files - a file pattern for email files. If not assigned,
# "*" will be used, which means all files will
# be treated as email files.
#
# search_string - the search string. Email files will be searched for
# this string. If not assigned, an empty search string will be
# used, which will return errors.
#
# Call this script as following.
#
# script "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
#
##################################################################
# Declare input arguments.
var string storagedir, files, search_string
# Is $storagedir assigned ? If not, assign current directory.
if ($storagedir == "")
scd > $storagedir
endif
# Is $files assigned ? If not, assign "*".
if ($files == "")
set $files = "*"
endif
# We don't need to check if $search_string is assigned. If not assigned, the script will return
# errors.
echo -e "DEBUG: Looking for search_string " $search_string " in files " $files " in directory " $storagedir
# Use the lf command to collect a list of email files. The first argument to the
# lf command is file pattern, we have that in $files. The second argument is
# the directory, we have that in $storagedir.
var string list
lf -rn $files $storagedir > $list
while ($list <> "")
do
# Get the next file into a string variable.
var string filedir
lex "1" $list > $filedir
# The next file is now in $filedir.
echo -e "DEBUG: Processing file " $filedir
# Is the $search_string present in file $filedir ?
var string output
script "filesearch.txt" file($filedir) search_string($search_string) > $output
if ($output == "Search string is present.")
do
# Search string is present. List file name and file contents.
echo "\n\n =========== EMAIL FILE " $filedir " =========== "
repro $filedir
done
endif
done
We will execute our script again, first with the -pl options, then without the -pl options.
Commands
script -pl "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
script "emailsearch.txt" storagedir("C:/LearningScripting/Lesson5") files("*.eml") search_string("joe")
Test the script in various ways with our test emails. Once you think it is working correctly,
you can do two things.
-
Remove all debug statements.
-
Move both scripts emailsearch.txt and filesearch.txt to directory C:/Scripts where they will be
available to everyone using your computer.
If you noticed, our emailserach.txt is actually rather small - without the comments and blank lines.
It has about 21 lines, which fits our recommendation of keeping the number of command lines in a script
small.
I will list the script below without comments and blank lines.
Script emailsearch.txt - without comments and blank lines
var string storagedir, files, search_string
if ($storagedir == "")
scd > $storagedir
endif
if ($files == "")
set $files = "*"
endif
var string list
lf -rn $files $storagedir > $list
while ($list <> "")
do
var string filedir
lex "1" $list > $filedir
var string output
script "filesearch.txt" file($filedir) search_string($search_string) > $output
if ($output == "Search string is present.")
do
echo "\n\n =========== EMAIL FILE " $filedir " =========== "
repro $filedir
done
endif
done
QUESTION 5.6
What search string can we use to find emails from email address <joe@8m906dh7.com> ?
Answer
A more general email search script is provided on the biterScripting web site as a sample script called
SS_FindEmailStrs .
DID YOU KNOW ?
-
When you enter a script command, and specify the script file using either the full path
or the relative path, how does biterScripting know where to find the script file ? If there
are two script files by the same name in two separate directories, how does biterScripting know
which one to use ? biterScripting finds (and uses) the script file in the following sequence.
-
If you specify the script file using full path, there is only one script file at that
full path. biterScripting will use that file.
-
If you specify the script file using relative path, biterScripting first checks if
a file by that name exists at that relative path, relative to the current directory.
If the file exists, it will be used. If not, biterScripting will continue its search
as below.
-
biterScripting will look at the value of the system variable $path. It contains
a list of directories separated by the verticle bar (|) (also known as a pipe). biterScripting
will check if the script file exists at the relative path you specified, relative to each
directory in this list. As soon as a file is found, it will use that file.
-
If after doing all of the above, still a file is not found, an error will be produced indicating
that the script file could not be found.
The value of $path is set by default to "C:/Scripts". (You can change this value.) It is thus best
to store all your 'proven' scripts in the directory C:/Scripts.
-
You can execute scripts directly from a web site. This is done by specifying the script file
with a web path. For example, the following command will execute script Prep5.txt
at the web address http://www.biterscripting.com/LearningScripting/.
Command
script "http://www.biterscripting.com/LearningScripting/Prep5.txt"
In fact, that's what we have been doing when we used the script command in preparation for
each of the lessons. (These preparation scripts were creating directories, downloading sample
files, etc. all needed for the lessons.)
Note that you can execute scripts from any web site, not only biterscripting.com. This means,
once you have written scripts that are working well, and you believe that your scripts will
be useful to others, you can publish your scripts on a web site. You can also post them
at various forums. (As a reverse consideration,
as always, make sure you understand
well the scripts written by other people, before you use them.)
SUMMARY
In this lesson, we learned
- The system command.
- The sen command.
- The file search mechanism.
- Several script development techniques.
- We developed an email search script.
HOMEWORK 5
-
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
-
Our script emailsearch.txt searches email files for one search string. Create a script called emailsearch2.txt
in directory C:/LearningScripting/Lesson5 that searches email files based on two search strings.
Instead of one input argument search_string, this script will take two input arguments - search_string1
and search_string2. It will list email files and their contents for files that contain both search
strings .
Answer
Well, that's it for the lessons. The next is exam.
Hopefully, you gained enough knowledge in these lessons to go on your own. We could not cover many
topics - other data types, expressions and conversion rules, variable overloading, global variables,
system functions, writing your own
functions, inline commands, automated editors, regular expressions,
use of biterScripting in batch mode, scheduling scripts
to run periodically using a scheduler, running scripts as part of a web server - to name a few.
You will come across these topics as you develop more advanced scripts. When more knowledge is needed,
always use the help pages, look at sample scripts, ask people who are experts in biterScripting for help.
We enjoyed working with you through these lessons. We wish you many productive, rewarding and
money-making scripting engagements.
Please don't forget to take the exam and submit your answers.
|
|
© 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.
|
|