Shell Scripts
We can save commands for later re-use in files called shell scripts.
Let's start by going back to ~/unix_intro/exercises/creatures and
creating a new file, my_first_sh_script.sh which will become our shell
script:
~/unix_intro/exercises/creatures
nano my_first_sh_script.sh
The command nano my_first_sh_script.sh opens creates an empty file
my_first_sh_script.sh. Now, we can use nanoto directly type in the
file - we'll simply insert the following line:
head -n 15 unicorn.dat | tail -n 5
This is a variation on the pipe we constructed earlier. Keep in mind, we
are not running it as a command just yet: we are putting the commands in
a file my_first_sh_script.sh using nano. Once we are done typing, we
can save the file (Ctrl+O), and exit nano (Ctrl+X).
Alternatively, we can simply create a file with echo command like
this:
echo "head -n 15 unicorn.dat | tail -n 5" > my_first_sh_script.sh
Check with ls if we successfully created a file called
my_first_sh_script.sh.
Once we have saved the file, we can ask the shell to execute the
commands it contains. Our shell is called bash, so we run the
following command:
bash my_first_sh_script.sh
What if we want to select lines from an arbitrary file? We could edit
my_first_sh_script.sh each time to change the filename, but that would
probably take longer than typing the command out again in the shell and
executing it with a new file name. Instead, let's edit
my_first_sh_script.sh and make it more versatile. Open
my_first_sh_script.sh with nano and replace unicorn.dat with the
special variable called $1:
head -n 15 "$1" | tail -n 5
Inside a shell script, $1 means the first filename (or other
arguments) on the command-line. We can now run our script like this:
bash my_first_sh_script.sh unicorn.dat
We still need to edit my_first_sh_script.sh each time we want to
adjust the range of lines, though. Let's fix that by using the special
variables $2 and $3 for the number of lines to be passed to head
and tail respectively. Open my_first_sh_script.sh with nano and
correct the code to look like this:
head -n "$2" "$1" | tail -n "$3"
Now we can test it (extract first 2 lines with head and only the last
one of those 2 with tail to get classification):
bash my_first_sh_script.sh unicorn.dat 2 1
So it seems that now script works, but it may take the next person who
reads my_first_sh_script.sh a moment to figure out what it does. We
can improve our script by adding some comments (A comment starts
with a # character and runs to the end of the line) at the top where
we can describe what does this script does. Open my_first_sh_script.sh
with nano and add comments at the top to look like this:
# Select desirable lines from a file.
# Usage: bash my_first_sh_script.sh filename end_line num_lines
head -n "$2" "$1" | tail -n "$3"
Task
Previously we used awk to print all the lines between 5000000 and
10000000. Let's make this awk script into bash script where we can
define which lines we want to print based on the interval which we can
change. To do so:
- Move to
~/unix_intro/exercises/genes - Make new bash script with
nanonamedprint_lines_between.sh - Inside write the code which we can use on any file and in such a way that we can select the interval whenever we run the script.
- Try your script with different
.gfffiles and with different intervals (e.g. between 100000 and 200000, or between 500000 and 1500000 forchrX.gffandchr9.gff).
Click for Tip
We have to know that awk and bash have different ways of calling variables so just as a hint - we will have to use awk option that passes bash variables to awk script -v.