Tips and tricks


The following sections expects that researchers are familiar wth the Linux command line, vi or (vim) editor. Any use of a username (such as john) should be substituted with the researcher's own Michigan Tech ISO username.

Prior to using a shell script, researchers will need to change its permission to at least 700, if not 755, via the chmod command as follows:

chmod 700 SCRIPT_NAME.sh

ARGUMENT indicates a mandatory/required argument for a given script, while [ARGUMENT] indicates an optional argument. Researchers may also clone the Research Computing Tips repository to get updated versions of these scripts.



Self-paced learning



BASH: Arithmetic (exponentiation)

#! /bin/bash
#
# BASH script for exponentiation (i.e., a raised to the power 'b').
#
# Usage: 
# exponentiation.sh NUMBER1 NUMBER2
 
 
# Necessary variables
EXPECTED_ARGS=2
 
# Check if two numbers are supplied at the command line. If not, print an 
# error message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0` NUMBER1 NUMBER2"
  echo "   e.g.: `basename $0` 4 2"
  echo "         `basename $0` -4 2.25"
  echo
  exit
fi
 
# Store the arguments
A=$1
B=$2
 
# Validate A and B
NUMERIC_INPUT='^-?[0-9]+([.][0-9]+)?$'
if ! [[ $A =~ $NUMERIC_INPUT ]]
then
  echo
  echo "  NUMBER1 is invalid"
  echo
  exit
fi
 
NUMERIC_INPUT='^-?[0-9]+?$'
if ! [[ $B =~ $NUMERIC_INPUT ]]
then
  echo
  echo "  NUMBER2 is invalid (non-integer)"
  echo
  exit
fi
 
# Arithmetic (exponentiation)
C=`echo "$A ^ $B" | bc -l`
 
# Print to screen
echo
echo "  NUMBER1 (A) : $A"
echo "  NUMBER2 (B) : $B"
echo "  C = A ^ B   : $C"
echo
 


BASH: Arithmetic (divide two numbers)

#! /bin/bash
#
# BASH script to divide two given numbers.
#
# Usage: 
# division.sh NUMBER1 NUMBER2
 
 
# Necessary variables
EXPECTED_ARGS=2
 
# Check if two numbers are supplied at the command line. If not, print an 
# error message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0` NUMBER1 NUMBER2"
  echo "   e.g.: `basename $0` 4 2"
  echo "         `basename $0` -4 2.25"
  echo
  exit
fi
 
# Store the arguments
A=$1
B=$2
 
# Validate A and B
NUMERIC_INPUT='^-?[0-9]+([.][0-9]+)?$'
if ! [[ $A =~ $NUMERIC_INPUT ]]
then
  echo
  echo "  NUMBER1 is invalid"
  echo
  exit
fi
 
if ! [[ $B =~ $NUMERIC_INPUT ]]
then
  echo
  echo "  NUMBER2 is invalid"
  echo
  exit
fi
 
if [ $B -eq 0 ]
then
  echo
  echo "  NUMBER2 cannot be zero"
  echo
  exit
fi
 
# Arithmetic (division)
C=`echo "$A / $B" | bc -l`
 
# Print to screen
echo
echo "  NUMBER1 (A) : $A"
echo "  NUMBER2 (B) : $B"
echo "  C = A / B   : $C"
echo
 


BASH: Arithmetic (multiply two numbers)

#! /bin/bash
#
# BASH script to multiply two given numbers.
#
# Usage: 
# multiplication.sh NUMBER1 NUMBER2
 
 
# Necessary variables
EXPECTED_ARGS=2
 
# Check if two numbers are supplied at the command line. If not, print an 
# error message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0` NUMBER1 NUMBER2"
  echo "   e.g.: `basename $0` 4 2"
  echo "         `basename $0` -4 2.25"
  echo
  exit
fi
 
# Store the arguments
A=$1
B=$2
 
# Validate A and B
NUMERIC_INPUT='^-?[0-9]+([.][0-9]+)?$'
if ! [[ $A =~ $NUMERIC_INPUT ]]
then
  echo
  echo "  NUMBER1 is invalid"
  echo
  exit
fi
 
if ! [[ $B =~ $NUMERIC_INPUT ]]
then
  echo
  echo "  NUMBER2 is invalid"
  echo
  exit
fi
 
# Arithmetic (multiplication)
C=`echo "$A * $B" | bc -l`
 
# Print to screen
echo
echo "  NUMBER1 (A) : $A"
echo "  NUMBER2 (B) : $B"
echo "  C = A * B   : $C"
echo
 


BASH: Arithmetic (subtract two numbers)

 


BASH: Arithmetic (add two numbers)

#! /bin/bash
#
# BASH script to add two given numbers.
#
# Usage: 
# addition.sh NUMBER1 NUMBER2
 
 
# Necessary variables
EXPECTED_ARGS=2
 
# Check if two numbers are supplied at the command line. If not, print an 
# error message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0` NUMBER1 NUMBER2"
  echo "   e.g.: `basename $0` 4 2"
  echo "         `basename $0` -4 2.25"
  echo
  exit
fi
 
# Store the arguments
A=$1
B=$2
 
# Validate A and B
NUMERIC_INPUT='^-?[0-9]+([.][0-9]+)?$'
if ! [[ $A =~ $NUMERIC_INPUT ]]
then
  echo
  echo "  NUMBER1 is invalid (contains non-numeric charcaters)"
  echo
  exit
fi
 
if ! [[ $B =~ $NUMERIC_INPUT ]]
then
  echo
  echo "  NUMBER2 is invalid (contains non-numeric charcaters)"
  echo
  exit
fi
 
# Arithmetic (addition)
C=`echo "$A + $B" | bc -l`
 
# Print to screen
echo
echo "  NUMBER1 (A) : $A"
echo "  NUMBER2 (B) : $B"
echo "  C = A + B   : $C"
echo
 


BASH: Read (and parse) a file one line at a time

#! /bin/bash
#
# BASH script to read a given file, one line at a time, and parse the line
# to accomplish a desired task.
#
# This particular script assumes that any line that is empty or any line that
# begins with # is less useful, and as such ignores them. The file used to
# demonstrate the script has four fields -- student name and her/his score in
# three assignments -- separated by |. The desired task is to display the 
# student name, individual assignment score as well as the cumulative score,
# average score, and an associated letter grade.
#
# Usage:
# read_file_line_by_line.sh FILENAME
 
 
# Necessary variables
EXPECTED_ARGUMENTS=1
 
# Check if a file is supplied at the command line. If not, print an error 
# message (help text) and exit
if [ $# -ne $EXPECTED_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0` FILENAME"
  echo "   e.g.: `basename $0` students.txt"
  echo
  exit
fi
 
# Function to convert score into letter grade
score2grade() {
 
  # Input
  local original_score=${1}
 
  # Sanitized score (strip off all non-numeric characters)
  sanitized_score=`echo "$original_score" | sed 's/[^0-9\.]//g'`
 
  # Assign a letter grade to sanitized score
  case $sanitized_score in
    100.00)
      echo "A"
    ;;
    9[0-9].[0-9][0-9])
      echo "A"
    ;;
    8[0-9].[0-9][0-9])
      echo "B"
    ;;
    7[0-9].[0-9][0-9])
      echo "C"
    ;;
    6[0-9].[0-9][0-9])
      echo "D"
    ;;
    [1-5][0-9].[0-9][0-9])
      echo "F"
    ;;
    [0-9].[0-9][0-9])
      echo "F"
    ;;
  esac
}
 
# Save the filename
FILENAME="$1"
 
# Check if file exists. If not, print an error message (help text) and exit
if [ ! -e "$FILENAME" ]
then
  echo
  echo "  $FILENAME does not exist."
  echo "  Exiting."
  echo
  exit
fi
 
# Check if file has zero size. If yes, print an error message (help text)
# and exit
FILE_SIZE=$(du $FILENAME | awk '{print $1}')
if [ "$FILE_SIZE" -eq 0 ]
then
  echo
  echo "  $FILENAME exists but is empty."
  echo "  Exiting."
  echo
  exit
fi
 
# Check if file has non-zero size but has any useful information. If not, 
# print an error message (help text) and exit
NON_BLANK_LINES=`sed '/^ *#/d;s/#.*//' $FILENAME | sed '/^$/d' | wc -l`
if [ "$NON_BLANK_LINES" -eq 0 ]
then
  echo
  echo "  $FILENAME exists and is not empty but has no useful information."
  echo "  Exiting."
  echo
  exit
fi
 
# Create a temporary sanitized file
SANITIZED_FILENAME="${FILENAME}_$$"
sed '/^ *#/d;s/#.*//' $FILENAME | sed  '/^$/d' > $SANITIZED_FILENAME
 
# Formatted output
i=0
echo
echo "  --------------------------------------------------------------"
printf "  %-2s  %-20s  %3s  %3s  %3s  %-5s  %-7s  %-5s\n" "##" "Student" "#1" "#2" "#3" "Total" "Average" "Grade"
echo "  --------------------------------------------------------------"
 
# Read through the sanitized file one line at a time
exec<$SANITIZED_FILENAME
while read student_info
do
  # Increment the index 'i'
  i=`expr $i + 1`
 
  STUDENT_NAME=`echo $student_info | awk -F '|' '{ print $1 }' | sed 's/^[ \t]*//;s/[ \t]*$//'`
  ASSIGNMENT_1=`echo $student_info | awk -F '|' '{ print $2 }' | sed 's/^[ \t]*//;s/[ \t]*$//'`
  ASSIGNMENT_2=`echo $student_info | awk -F '|' '{ print $3 }' | sed 's/^[ \t]*//;s/[ \t]*$//'`
  ASSIGNMENT_3=`echo $student_info | awk -F '|' '{ print $4 }' | sed 's/^[ \t]*//;s/[ \t]*$//'`
  TOTAL_SCORE=`echo "$ASSIGNMENT_1 + $ASSIGNMENT_2 + $ASSIGNMENT_3" | bc`
  AVERAGE_SCORE=`echo "scale=2; $TOTAL_SCORE/3" | bc`
  LETTER_GRADE=`score2grade $AVERAGE_SCORE`
  printf "  %2d  %-20s  %3d  %3d  %3d  %5d  %7s  %5s\n" "$i" "$STUDENT_NAME" "$ASSIGNMENT_1" "$ASSIGNMENT_2" "$ASSIGNMENT_3" "$TOTAL_SCORE" "$AVERAGE_SCORE" "$LETTER_GRADE"
done
 
# Formatted output
echo "  --------------------------------------------------------------"
echo
 
# Delete the temporary sanitized file
rm -f $SANITIZED_FILENAME
 



students.txt



BASH: List files with a given name in a given location

#! /bin/bash
#
# BASH script to list all files in a given directory that have PART_OF_THE_NAME
# as part of their name.
# 
# If option -h is specified with any other option, -h takes precedence over 
# all other options.
#
# Usage: 
# list_file_by_name.sh -h
# list_file_by_name.sh [-l LOCATION] [-f PART_OF_THE_NAME]
 
 
# Function to display error message (help text)
show_help() {
  echo
  echo "  Usage: `basename $0` -h"
  echo "         `basename $0` [-l LOCATION] [-f PART_OF_THE_NAME]"
  echo
  echo "    e.g. `basename $0`"
  echo "         `basename $0` -f txt"
  echo "         `basename $0` -l /research/john"
  echo "         `basename $0` -l /research/john -f txt"
  echo
  exit
}
 
# -l and -f must have parameter values
# -h doesn't need a parameter value
while getopts :l:f:h option
do
  case "$option" in
 
    # -h
    h)
      show_help
      ;;
 
    # -l
    l)
      # If -l is specified with no value, display help
      if [ -n $OPTARG ]
      then
        LOCATION="$OPTARG"
      else
        show_help
      fi
      ;;
 
    # -f
    f)
      # If -f is specified with no value, display help
      if [ -n $OPTARG ]
      then
        NAME="$OPTARG"
      else
        show_help
      fi
      ;;
  esac
done
 
# If NAME is empty, then assume any file type
if [ -z $NAME ]
then
  NAME="*"
fi
 
# If LOCATION is empty, then assume present working directory
if [ -z $LOCATION ]
then
  LOCATION=`pwd`
fi
 
# List all files that that match the criteria
echo
echo "  Location           : $LOCATION"
echo "  File name contains : $NAME"
echo
find $LOCATION -iname "*$NAME*" | sort
echo
 


BASH: Reminder utility (Part #2: search through the notes)

#! /bin/bash
#
# BASH script to search through quick notes stored using 'remember_me.sh'.
#
# Usage:
# remind_me.sh SEARCH_STRING
 
 
# Necessary variables
MINIMUM_ARGS=1
 
# Check if a string supplied at the command line. If not, 
# print an error message (help text) and exit
if [ $# -lt $MINIMUM_ARGS ]
then
  echo
  echo "  Usage: `basename $0` SEARCH_STRING"
  echo "   e.g.: `basename $0` michigan"
  echo "         `basename $0` michigan tech"
  echo
  exit
fi
 
# Necessary variables
REMEMBER="$HOME/.remember"
SEARCH_STRING="$@"
 
# Search through the stored notes (case insensitive search) and display all
# matching entries with time stamp
grep -B1 -i "$SEARCH_STRING" $REMEMBER
 


BASH: Reminder utility (Part #1: save the note)

#! /bin/bash
#
# BASH script to store quick (i.e., one line) notes for a later reference.
# Use 'remind_me.sh' to search through the stored quick notes.
#
# Usage:
# remember_me.sh
 
 
# Necessary variables
EXPECTED_ARGS=0
 
# Check if the script is called with no options. If not, print an error 
# message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0`"
  echo
  exit
fi
 
# Necessary variables
REMEMBER="$HOME/.remember"
DATE_TIME=`date -R`
 
# Prompt the user for a note to remembered
echo "Enter a quick note to remember [press ENTER key when done]"
read NOTE2REMEMBER
NOTE2REMEMBER_SANITIZED=`echo ${NOTE2REMEMBER} | sed 's/^[ \t]*//;s/[ \t]*$//'`
 
# Record the note along with the time stamp
echo "# $DATE_TIME"             >> $REMEMBER
echo "$NOTE2REMEMBER_SANITIZED" >> $REMEMBER
echo
 


BASH: Time conversion (seconds to human readable format)

#! /bin/bash
#
# BASH script to convert seconds into human readable format.
#
# Usage:
# seconds2hrf.sh SECONDS
 
 
# Necessary variables
EXPECTED_ARGS=1
 
# Check if number of seconds is supplied at the command line. If not, 
# print an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0` SECONDS"
  echo "   e.g.: `basename $0` 1234"
  echo
  exit
fi
 
# Save the number of seconds
SECONDS="$1"
 
# Convert seconds to days, hours, minutes and seconds
DD=`echo "$SECONDS/86400" | bc`
HH=`echo "$SECONDS%86400/3600" | bc`
MM=`echo "$SECONDS%3600/60" | bc`
SS=`echo "$SECONDS%60" | bc`
 
# Print the result to the screen
printf "%d:%02d:%02d:%02d\n" $DD $HH $MM $SS
 


Gnuplot: Iterative plot (multiple datasets)

# iterative_plot_datasets.gnu
# 
# Usage:
# gnuplot iterative_plot_datasets.gnu
 
 
set terminal pngcairo dashed size 1280,800 enhanced font 'Helvetica,24'
set output "iterative_plot_datasets.png"
set title  "Iterative plot of multiple data sets (Amdahl's Law)"
set xlabel "# of processors"
set ylabel "Speed up"
set yrange [0:21]
set logscale x 2
set key left top
set key autotitle columnhead
set grid
 
plot for [i=1:7] 'dataset_'.i.'.dat' using 1:2 with lines lw 1
 



iterative_plot_datasets.png
generate_datasets.sh
dataset_1.dat | dataset_2.dat | dataset_3.dat | dataset_4.dat | dataset_5.dat | dataset_6.dat | dataset_7.dat



Gnuplot: Iterative plot (sine function; filled/translucent)

# iterative_plot_sine_filled.gnu
# 
# Usage:
# gnuplot iterative_plot_sine_filled.gnu
 
 
set terminal pngcairo size 1280,800 enhanced font 'Helvetica,24'
set output "iterative_plot_sine_filled.png"
set title  "Iterative plot (filled/translucent)"
set xlabel "x"
set ylabel "sin(x*n)/n"
set xrange [0.00:6.28] noreverse nowriteback
set yrange [-1.1:1.1]
set grid
set style fill transparent solid 0.25 noborder
set sample 1000
 
plot for [n=1:5] sin(x*n)/n notitle with filledcurves
 



iterative_plot_sine_filled.png



Gnuplot: Iterative plot (sine function; line)

# iterative_plot_sine_lines.gnu
# 
# Usage:
# gnuplot iterative_plot_sine_lines.gnu
 
 
set terminal pngcairo size 1280,800 enhanced font 'Helvetica,24'
set output "iterative_plot_sine_lines.png"
set title  "Iterative plot (lines)"
set xlabel "x"
set ylabel "sin(x*n)/n"
set xrange [0.00:3.00] noreverse nowriteback
set yrange [-0.6:0.6]
set grid
set style data lines
set sample 500
 
plot for [n=2:10] sin(x*n)/n notitle lw (13-n)/2
 



iterative_plot_sine_lines.png



Gnuplot: Iterative plot (Bessel function; filled)

# filled_curves_bessel.gnu
# 
# Usage:
# gnuplot filled_curves_bessel.gnu
 
 
set terminal pngcairo size 1280,800 enhanced font 'Helvetica,24'
set output "filled_curves_bessel.png"
set title  "Iterative plot (filled/translucent)"
set xlabel "x"
set ylabel "J_n(x)"
set xrange [0:25]
set yrange [-0.5:1]
set grid
 
set style fill transparent solid 0.25 noborder
set style function filledcurves y1=0
set sample 5000
 
besj2(x)  = 2*1/x * besj1(x) - besj0(x)
besj3(x)  = 2*2/x * besj2(x) - besj1(x)
besj0_(x) = x<5 ? besj0(x) : 1/0
 
plot besj0(x) fs transparent solid 0.80 noborder t 'J_0(x)' , \
     besj1(x) fs transparent solid 0.60 noborder t 'J_1(x)' , \
     besj2(x) fs transparent solid 0.40 noborder t 'J_2(x)' , \
     besj3(x) fs transparent solid 0.20 noborder t 'J_3(x)' 
 



filled_curves_bessel.png



Gnuplot: Filled curves (Probabilty intensity; translucent)

# filled_curves_probability.gnu
# 
# Usage:
# gnuplot filled_curves_probability.gnu
 
 
set terminal pngcairo size 1280,800 enhanced font 'Helvetica,24'
set output "filled_curves_probability.png"
set title  "Filled curves (translucent)"
set xlabel "x"
set ylabel "Probability Intensity f(v)"
set grid
set key top right
set style fill transparent solid 0.5 noborder
 
f(v,T)=4/sqrt(pi*T**3)*exp(-v**2/T)*v**2
set sample 500
plot [0:5] f(x,0.1) with filledcurves x1 title "T=0.1",\
           f(x,1)   with filledcurves x1 title "T=1.0",\
           f(x,5)   with filledcurves x1 title "T=5.0"
 



filled_curves_probability.png



Gnuplot: Filled curves (Gaussian function; solid)

# filled_curves_gaussian.gnu
# 
# Usage:
# gnuplot filled_curves_gaussian.gnu
 
 
set terminal postscript eps enhanced color "Helvetica" 24
set output "filled_curves_gaussian.eps"
set size 2.0,2.0
set title  "Filled curves (solid)"
set xlabel "x"
set ylabel "Gaussian"
 
set style fill solid 1.0 noborder
set style function filledcurves y1=0
set clip two
 
Gauss(x,mu,sigma) = 1./(sigma*sqrt(2*pi)) * exp( -(x-mu)**2 / (2*sigma**2) )
d1(x) = Gauss(x, 0.5, 0.75)
d2(x) = Gauss(x, 1.0, 2.00)
d3(x) = Gauss(x, 4.0, 3.00)
 
set xrange [-6:10]
set yrange [0:1]
unset colorbox
set key top left Left reverse samplen 1
 
plot d1(x) fs solid 1.0 lc rgb "forest-green" title "{/Symbol m} =  0.5; {/Symbol s} = 0.5", \
     d2(x) lc rgb "gold" title "{/Symbol m} =  2.0; {/Symbol s} = 1.0", \
     d3(x) lc rgb "red" title "{/Symbol m} = -1.0; {/Symbol s} = 2.0"
 



filled_curves_gaussian.eps



Gnuplot: Curve fit with error bar

# curve_fit_error_bar.gnu
# 
# Gnuplot instructions to plot the data contained in 
# curve_fit_error_bar.dat with error bars.
#
# Usage:
# gnuplot curve_fit_error_bar.gnu
 
 
set terminal postscript eps enhanced color "Helvetica" 24
set output "curve_fit_error_bar.eps"
set size 2.0,2.0
set title  "Linear curve fit and error bar"
set xlabel "# of processors"
set ylabel "Measured quantity"
set samples 100
set xrange [0:18]
set grid
 
fit a*x + b 'curve_fit_error_bar.dat' using 1:2:3 via a,b
plot 'curve_fit_error_bar.dat' title 'Error bar' with errorbars lw 2, a*x + b title 'Curve fit' lw 2 lt 1 lc 3
 



curve_fit_error_bar.dat | curve_fit_error_bar.eps | curve_fit_error_bar.log



Gnuplot: Curve fit (cubic)

# curve_fit_cubic.gnu
# 
# Gnuplot instructions to plot the data contained in 
# curve_fit.dat.
#
# Usage:
# gnuplot curve_fit_cubic.gnu
 
 
set terminal postscript eps enhanced color "Helvetica" 24
set output "curve_fit_cubic.eps"
set size 2.0,2.0
set title  "Curve fit (cubic)"
set xlabel "# of processors"
set ylabel "Measured quantity"
set samples 100
set xrange [0:18]
set grid
set key bottom right
 
fit a*x*x*x + b*x*x + c*x + d 'curve_fit.dat' using 1:2 via a,b,c,d
plot 'curve_fit.dat' using 1:2 title 'Measured data' with points lc 4 pt 5, a*x*x*x + b*x*x + c*x + d title 'Curve fit' lw 2 lt 1 lc 8
 



curve_fit.dat | curve_fit_cubic.eps | curve_fit_cubic.log



Gnuplot: Curve fit (quadratic)

# curve_fit_quadratic.gnu
# 
# Gnuplot instructions to plot the data contained in 
# curve_fit.dat.
#
# Usage:
# gnuplot curve_fit_quadratic.gnu
 
 
set terminal postscript eps enhanced color "Helvetica" 24
set output "curve_fit_quadratic.eps"
set size 2.0,2.0
set title  "Curve fit (quadratic)"
set xlabel "# of processors"
set ylabel "Measured quantity"
set samples 100
set xrange [0:18]
set grid
set key bottom right
 
fit a*x*x + b*x + c 'curve_fit.dat' using 1:2 via a,b,c
plot 'curve_fit.dat' using 1:2 title 'Measured data' with points pt 5, a*x*x + b*x + c title 'Curve fit' lw 2 lt 1 lc 5
 



curve_fit.dat | curve_fit_quadratic.eps | curve_fit_quadratic.log



Gnuplot: Curve fit (linear)

# curve_fit_linear.gnu
# 
# Gnuplot instructions to plot the data contained in 
# curve_fit.dat.
#
# Usage:
# gnuplot curve_fit_linear.gnu
 
 
set terminal postscript eps enhanced color "Helvetica" 24
set output "curve_fit_linear.eps"
set size 2.0,2.0
set title  "Curve fit (linear)"
set xlabel "# of processors"
set ylabel "Measured quantity"
set samples 100
set xrange [0:18]
set grid
set key bottom right
 
fit a*x + b 'curve_fit.dat' using 1:2 via a,b
plot 'curve_fit.dat' using 1:2 title 'Measured data' with points pt 5, a*x + b title 'Curve fit' lw 2 lt 1 lc 5
 



curve_fit.dat | curve_fit_linear.eps | curve_fit_linear.log



Gnuplot: Mathematical functions (trigonometric)

# trigonometric_functions.gnu
# 
# Usage:
# gnuplot trigonometric_functions.gnu
 
 
set terminal postscript eps enhanced color "Helvetica" 24
set output "trigonometric_functions.eps"
set size 2.0,2.0
set title  "Trigonometric functions"
set xlabel "x"
set ylabel "sin(x), arctan(x), cos(arctan(x))"
set xrange [0:18]
set grid
set key outside
plot [-15:15] sin(x) title "sin(x)" with linesp lt 8 pt 5, \
              atan(x) title "arctan(x)" with linesp lt 3 pt 4, \
              cos(atan(x)) title "cos(arctan(x))" with impulses lt 9
 



trigonometric_functions.eps



Gnuplot: 3D plot projected onto a 2D surface

# 3d_plot_2d_projection.gnu
# 
# Gnuplot instructions to plot the data contained in 
# 3d_plot_2d_projection.dat.
#
# Usage:
# gnuplot 3d_plot_2d_projection.gnu
 
 
set terminal postscript eps enhanced color "Helvetica" 24
set output "3d_plot_2d_projection.eps"
set size 2.0,2.0
set title  "2 dimensional heat map"
set xlabel "# of atoms"
set ylabel "# of processors"
set ticslevel 0.2
set grid
set dgrid3d
set hidden3d
set pm3d map
set nokey
splot '3d_plot_2d_projection.dat' using 1:2:3 with pm3d
 



3d_plot_2d_projection.dat | 3d_plot_2d_projection.eps



Gnuplot: 3D plot

# 3d_plot.gnu
# 
# Gnuplot instructions to plot the data contained in 3d_plot.dat.
#
# Usage:
# gnuplot 3d_plot.gnu
 
 
set terminal postscript eps enhanced color "Helvetica" 24
set output "3d_plot.eps"
set size 2.0,2.0
set title  "3 dimensional plot"
set xlabel "# of atoms"
set ylabel "# of processors"
# set zlabel "Wall Time (seconds)"
set ticslevel 0.2
set grid
set dgrid3d 30,30
set hidden3d
set pm3d
set nokey
# Plot
splot '3d_plot.dat' using 1:2:3 with pm3d
 



3d_plot.dat | 3d_plot.eps



Gnuplot: Multiple plots using multiple data sets from a single file

# multiple_data_sets_single_file.gnu
# 
# Gnuplot instructions to plot the data contained in 
# multiple_data_sets_single_file.dat.
#
# Usage:
# gnuplot multiple_data_sets_single_file.gnu
 
 
set terminal postscript eps enhanced color "Helvetica" 24
set output "multiple_data_sets_single_file.eps"
set size 2.0,2.0
set title  "Multiple sets of data points from one file"
set xlabel "# of processors"
set ylabel "Time (seconds)"
set xrange [0:18]
set grid
plot 'multiple_data_sets_single_file.dat' using 1:2 title "# of atoms = 6"  with linesp lt 1 pt 5, \
     'multiple_data_sets_single_file.dat' using 1:3 title "# of atoms = 8"  with linesp lt 2 pt 4, \
     'multiple_data_sets_single_file.dat' using 1:4 title "# of atoms = 10" with linesp lt 3 pt 3
 



multiple_data_sets_single_file.dat | multiple_data_sets_single_file.eps



Gnuplot: Single plot using a single data set from a single file

# single_data_set_single_file.gnu
# 
# Gnuplot instructions to plot the data contained in 
# single_data_set_single_file.dat.
#
# Usage:
# gnuplot single_data_set_single_file.gnu
 
 
set terminal postscript eps enhanced color "Helvetica" 24
set output "single_data_set_single_file.eps"
set size 2.0,2.0
set title  "One set of data points from one file"
set xlabel "# of processors"
set ylabel "Time (seconds)"
set xrange [0:18]
set grid
plot 'single_data_set_single_file.dat' using 1:2 title "# of atoms = 10" with linesp lt 1 pt 5
 



single_data_set_single_file.dat | single_data_set_single_file.eps



BASH: Check file usefulness

#! /bin/bash
#
# BASH script to check if a file has useful information.
# Applications include checking if a file contains non-comment characters
# before proceeding ahead with parsing/processing it.
#
# Usage:
# check_file_usefulness.sh FILENAME
 
 
# Necessary variables
EXPECTED_ARGS=1
 
# Check if a filename is supplied at the command line. If not, print 
# an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0` FILENAME"
  echo "   e.g.: `basename $0` sample.tex"
  echo "         `basename $0` sample.txt"
  echo
  exit
fi
 
# Save the filename
export FILENAME="$1"
 
# Check if file has non-zero size but has any useful information. If not, 
# print an error message (help text) and exit
# '%' is the comment character in MATLAB and LaTeX. Replace it with the
# appropriate comment character for a different language ('#' for shell
# scripting and PHP, etc.)
NON_BLANK_LINES=`sed '/^ *%/d;s/%.*//' $FILENAME | sed '/^$/d' | wc -l`
if [ "$NON_BLANK_LINES" -eq 0 ]
then
  echo
  echo "  $FILENAME exists and is not empty but has no useful information."
  echo "  Exiting."
  echo
  exit
fi
 


BASH: Check file size

#! /bin/bash
#
# BASH script to check if a file has non-zero size.
# Applications include checking if a file has non-zero size, along with
# existence check (check_file_existence.sh), before proceeding ahead with
# parsing/processing it.
#
# Usage:
# check_file_size.sh FILENAME
 
 
# Necessary variables
EXPECTED_ARGS=1
 
# Check if a filename is supplied at the command line. If not, print 
# an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0` LATEX_FILENAME"
  echo "   e.g.: `basename $0` sample.tex"
  echo
  exit
fi
 
# Save the filename
export FILENAME="$1"
 
# Check if the file has zero size. If yes, print an error message (help text)
# and exit
FILE_SIZE=$(du $FILENAME | awk '{print $1}')
if [ "$FILE_SIZE" -eq 0 ]
then
  echo
  echo "  $FILENAME exists but is empty."
  echo "  Exiting."
  echo
  exit
fi
 


BASH: Check file existence

#! /bin/bash
#
# BASH script to check if a file exists.
# Applications include checking if a file exists before proceeding ahead with
# parsing/processing it.
#
# Usage:
# check_file_existence.sh FILENAME
 
 
# Necessary variables
EXPECTED_ARGS=1
 
# Check if a filename is supplied at the command line. If not, print 
# an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0` FILENAME"
  echo "   e.g.: `basename $0` sample.tex"
  echo "         `basename $0` sample.txt"
  echo
  exit
fi
 
# Save the filename
export FILENAME="$1"
 
# Check if the file exists. If not, print an error message (help text) and exit
if [ ! -e "$FILENAME" ]
then
  echo
  echo "  $FILENAME does not exist."
  echo "  Exiting."
  echo
  exit
fi
 


BASH: LaTeX+BibTeX compilation

#! /bin/bash
#
# BASH script to run LaTeX+BibTeX and convert the DVI to PDF.
# It also removes unncessary files.
#
# Usage:
# lbtex.sh LATEX_FILENAME
 
 
# Necessary variables
EXPECTED_ARGS=1
 
# Check if a LaTeX file is supplied at the command line. If not, print 
# an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0` LATEX_FILENAME"
  echo "   e.g.: `basename $0` sample.tex"
  echo
  exit
fi
 
# Save the filename and extract the basename (i.e., without .tex)
export FILENAME="$1"
export BASENAME=`echo "$FILENAME"  | awk -F '.' '{ print $1 }'`
 
# Run LaTeX twice, BibTeX twice, LaTeX twice and convert DVI to PDF.
# If need be, convert DVI to PS and then PS to PDF
echo
echo "  Running LaTeX on $FILENAME and convert to PDF"
latex  $FILENAME &> /dev/null
latex  $FILENAME &> /dev/null
bibtex $BASENAME &> /dev/null
bibtex $BASENAME &> /dev/null
latex  $FILENAME &> /dev/null
latex  $FILENAME &> /dev/null
dvipdf $BASENAME.dvi $BASENAME.pdf
 
# Delete unnecessary files
echo "  ... Done ... Now deleting unnecessary files"
rm -f $BASENAME.aux $BASENAME.out $BASENAME.toc 
rm -f $BASENAME.lof $BASENAME.lot $BASENAME.log 
rm -f $BASENAME.blg $BASENAME.lot $BASENAME.bbl 
echo "  ... Done"
echo
 


BASH: LaTeX compilation

#! /bin/bash
#
# BASH script to run LaTeX and convert the DVI to PDF.
# It also removes unncessary files.
#
# Usage:
# ltex.sh LATEX_FILENAME
 
 
# Necessary variables
EXPECTED_ARGS=1
 
# Check if a LaTeX file is supplied at the command line. If not, print 
# an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGS ]
then
  echo
  echo "  Usage: `basename $0` LATEX_FILENAME"
  echo "   e.g.: `basename $0` sample.tex"
  echo
  exit
fi
 
# Save the filename and extract the basename (i.e., without .tex)
export FILENAME="$1"
export BASENAME=`echo "$FILENAME"  | awk -F '.' '{ print $1 }'`
 
# Run LaTeX twice and convert DVI to PDF.
# If need be, convert DVI to PS and then PS to PDF
echo
echo "  Running LaTeX on $FILENAME and converting to PDF"
latex  $FILENAME &> /dev/null
latex  $FILENAME &> /dev/null
dvipdf $BASENAME.dvi $BASENAME.pdf
 
# Delete unnecessary files
echo "  ... Done ... Now deleting unnecessary files"
rm -f $BASENAME.aux $BASENAME.out $BASENAME.toc 
rm -f $BASENAME.lof $BASENAME.lot $BASENAME.log 
echo "  ... Done"
echo
 


BASH: Spell check

#! /bin/bash
#
# BASH script to check the spelling of a given (set of) word(s).
#
# Usage: 
# spell_check.sh WORD1 [WORD2] ... [WORDn]
 
 
# Necessary variables
MINIMUM_ARGUMENTS=1
 
# Check if a word (or more) is supplied at the command line. If not, print
# an error message (help text) and exit
if [ $# -lt $MINIMUM_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0` WORD1 [WORD2] ... [WORDn]"
  echo "   e.g.: `basename $0` spelling"
  echo "         `basename $0` spelling spleling wonder"
  echo
  exit
fi
 
# Variables
SPELL="ispell -l"
 
# Formatted output
i=1
echo
echo "  ---------------------------------"
echo "    ##  Word            Spelling"
echo "  ---------------------------------"
 
# Check the spelling of each supplied word
for word
do
  if [ -z $(echo $word | $SPELL) ]
  then
    printf "    %02d  %-14s  %s\n"  "$i" "$word" "Correct"
  else
    printf "    %02d  %-14s  %s\n"  "$i" "$word" "Incorrect"
  fi
 
  # Increment the index 'i'
  i=`expr $i + 1`
done
 
# Formatted output
echo "  ---------------------------------"
echo
 


BASH: Root check

#! /bin/bash
#
# BASH script to check if the currently logged in user is root. 
# Applications include scripts that need to be run only as root.
#
# Usage: 
# root_check.sh
 
 
# Check if the currently logged in user is root using the value of
# UID variable. If not, print an error message (help text) and exit
if [ $UID != 0 ]
then
  echo
  echo "  Not logged in as root! Exiting."
  echo
  exit
fi
 


BASH: Validate IP address

#! /bin/bash
#
# BASH script to check if a given string is an IP address (IPv4).
# 
# Usage: 
# validate_ip_address.sh IP_ADDRESS
 
 
# Necessary variables
EXPECTED_ARGUMENTS=1
 
# Check if an IP address is supplied at the command line. If not, print an 
# error message (help text) and exit
if [ $# -ne $EXPECTED_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0` IP_ADDRESS"
  echo "   e.g.: `basename $0` 123.456.789.012"
  echo
  exit
fi
 
# Variables
IP_ADDRESS="$1"
 
# Check if the supplied IP address is in the format ###.####.###.####
# i.e., if IP address is a set of 4 integers separated by '.'
if [[ $IP_ADDRESS =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
then
 
  # Save the current/default Internal Field Separator
  OIFS=$IFS
 
  # Set the default Internal Field Separator to '.'
  IFS='.'
 
  # Split the string IP_ADDRESS into an array using the new IFS as the
  # field separator
  OCTETS=($IP_ADDRESS)
 
  # Restore the Internal Field Separator to its default value
  IFS=$OIFS
 
  # Check if each element of the array is less than 255
  if [[ ${OCTETS[0]} -le 255    && ${OCTETS[1]} -le 255 \
       && ${OCTETS[2]} -le 255 && ${OCTETS[3]} -le 255 ]]
  then
    echo
    echo "    $IP_ADDRESS is valid"
    echo
  else
    echo
    echo "    $IP_ADDRESS is invalid"
    echo
  fi
else
  echo
  echo "    $IP_ADDRESS is invalid"
  echo
fi
 


BASH: Remote server status

#! /bin/bash
#
# BASH script to ping a given remote server identified by an IP address. 
# Applications include using this as a preliminary test of 'remote server 
# being alive' before attempting to transfer files (e.g., data backup via 
# cron jobs, etc.). 
#
# Potential enhancements include validating the IP address.
# 
# Usage: 
# remote_server_status.sh IP_ADDRESS
 
 
# Necessary variables
EXPECTED_ARGUMENTS=1
 
# Check if an IP address is supplied at the command line. If not, print an 
# error message (help text) and exit
if [ $# -ne $EXPECTED_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0` IP_ADDRESS"
  echo "   e.g.: `basename $0` 123.456.789.012"
  echo
  exit
fi
 
# Variables
SERVER="$1"
PING_COUNT=20
 
# Ping the remote server N times quietly
#   Select the line that contains "packet loss"
PING_REQUESTS=`ping -c $PING_COUNT -q $SERVER | \
                 grep "packet loss"`
 
# Count the number of pings (KNOCK_KNOCK), number of responses (WHO_IS_THERE) 
# and create a status for the network and/or the remote server
KNOCK_KNOCK=`echo $PING_REQUESTS | \
               awk -F ' ' '{ print $1 }'`
WHO_IS_THERE=`echo $PING_REQUESTS | \
                awk -F ' ' '{ print $4 }'`
 
if [ $WHO_IS_THERE -eq $KNOCK_KNOCK ]
then
  STATUS="Excellent"
else
  # 75% packets received
  if [ $WHO_IS_THERE -le `echo "scale=0; $KNOCK_KNOCK * (3/4)" | bc` ]
  then
    STATUS="Average"
  fi
 
  # 50% packets received
  if [ $WHO_IS_THERE -le `echo "scale=0; $KNOCK_KNOCK * (2/4)" | bc` ]
  then
    STATUS="Poor"
  fi
 
  # 25% packets received
  if [ $WHO_IS_THERE -le `echo "scale=0; $KNOCK_KNOCK * (1/4)" | bc` ]
  then
    STATUS="Very poor"
  fi
 
  # 0 packets received
  if [ $WHO_IS_THERE -eq 0 ]
  then
    STATUS="Down"
  fi
fi
 
# Print the information
echo
echo "  ---------------------------------------------------"
echo "                       -- Ping --    Server/Network"
echo "    Remote server      Sent  Recd        status"
echo "  ---------------------------------------------------"
printf "    %-15s    %02d    %02d      %s\n" "$SERVER" "$KNOCK_KNOCK" "$WHO_IS_THERE" "$STATUS"
echo "  ---------------------------------------------------"
echo
 


BASH: List IP address

#! /bin/bash
#
# BASH script to list all network interfaces and the associated IP address.
# 
# Usage: 
# list_ip_address.sh
 
 
# Necessary variables
EXPECTED_ARGUMENTS=0
 
# Check if there is any argument supplied at the command line. If yes, print 
# an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0`"
  echo
  exit
fi
 
# List all network interfaces
#   'netstat -i' provides the list
#   Delete the first two lines using 'sed'
#   Extract the first column using 'awk'
NETWORK_INTERFACES=`netstat -i   | \
                      sed '1,2d' | \
                      awk -F ' ' '{ print $1 }'`
 
# Formatted output
i=1
echo
echo "  ----------------------------------------"
echo "    ##  Interface  IP Address and Subnet "
echo "  ----------------------------------------"
 
# IP address associated with each network interface
for x in $NETWORK_INTERFACES
do
  # 'ip' lists all information associated with a
  # given network interface
  #   Retain only the line that has "inet " using 'grep'
  #   Extract the secont column using 'awk'
  IP_ADDRESS_SUBNET=`ip addr show $x | \
                       grep "inet "  | \
                       awk -F ' ' '{ print $2 }'`
 
  # Print the information
  printf "    %02d  %-9s  %s\n" "$i" "$x" "$IP_ADDRESS_SUBNET"
 
  # Increment the index 'i'
  i=`expr $i + 1`
done
 
# Formatted output
echo "  ----------------------------------------"
echo
 


BASH: Compile Gnuplot

#! /bin/bash
#
# BASH script to download and compile GNUPlot. When completed, it will also 
# create a symbolic link in $HOME/bin/
#
# Usage:
# compile_gnuplot.sh GNUPLOT_VERSION
 
 
# Necessary variables
EXPECTED_ARGUMENTS=1
 
# Check if more/less than the expected number of arguments have been supplied 
# at the command line. If yes, print an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0` GNUPLOT_VERSION"
  echo "   e.g.: `basename $0` 4.6.4"
  echo
  exit
fi
 
# Additional variables
GNUPLOT_VERSION="$1"
COMPILER="gcc"
COMPILER_VERSION="4.4.6"
CC="gcc"
CXX="g++"
FC="gfortran"
F77="gfortran"
TODAY=`/bin/date +"%Y%m%d_%H%M%S"`
 
# Installation specific variables
GNUPLOT_SOURCE="gnuplot-$GNUPLOT_VERSION.tar.gz"
GNUPLOT_INSTALL="$HOME/local/gnuplot/$GNUPLOT_VERSION/$COMPILER/$COMPILER_VERSION"
GNUPLOT_WEBSITE="http://sourceforge.net/projects/gnuplot/files/gnuplot"
 
# Check if the source code (gnuplot-GNUPLOT_VERSION.tar.gz) already exists in 
# the current folder. If yes, use it. If not, download it
if [ ! -e "${GNUPLOT_SOURCE}" ]
then
  wget $GNUPLOT_WEBSITE/$GNUPLOT_VERSION/$GNUPLOT_SOURCE
fi
 
# Create the installation location (must be writable)
mkdir -p $GNUPLOT_INSTALL
 
# Create a temporary folder and extract GNUPlot source code
mkdir ./tmp
cd ./tmp
tar -zxvf ../$GNUPLOT_SOURCE
 
# Run configure, make clean, make, make install
cd gnuplot-${GNUPLOT_VERSION}/
./configure --prefix=$GNUPLOT_INSTALL 2>&1 | tee configure_$TODAY.txt
make clean                            2>&1 | tee make-clean_$TODAY.txt
make                                  2>&1 | tee make_$TODAY.txt
make install                          2>&1 | tee make-install_$TODAY.txt
 
# Remove ./tmp
cd ../../
\rm -r ./tmp
 
# Create symbolic link in $HOME/bin
mkdir -p $HOME/bin
cd $HOME/bin
ln -sf $GNUPLOT_INSTALL/bin/gnuplot gnuplot
echo
 


BASH: Input validation

#! /bin/bash
#
# BASH script to validate user input. Each function makes sure a user's input 
# is alphabetical, numeric or alphanumeric. 
#
# Technique is to strip off all non-desired characters from the string 
# (user input) using 'sed' ('tr' and 'awk' may also be used to accomplish this 
# task). If the stripped version is identical to the original string, then the 
# user input is valid (exit value: 0); invalid otherwise (exit value: 1).
#
# A recommended way is to store these functions in a separate file (say, 
# functions.sh) and source them for general use by more than one shell script.
# 
# Usage:
# input_validation.sh
 
 
# Necessary variables
EXPECTED_ARGUMENTS=0
 
# Check if more than the expected number of arguments have been supplied at 
# the command line. If yes, print an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0`"
  echo
  exit
fi
 
# Function #1: alphabetic input
validate_alphabetic() {
 
  # User input
  local original_string=${1}
 
  # Strip off all non-alphabetic characters from original_string
  sanitized_string=`echo "$original_string" | sed 's/[^a-zA-Z]//g'`
 
  # Compare original_string and sanitized_string, and return a value
  if [ "$original_string" != "$sanitized_string" ]
  then
    # Invalid user input
    return 1
  else
    # Valid user input
    return 0
  fi
}
# Function #1: alphabetic input
 
# Function #2: numeric input
validate_numeric() {
 
  # User input
  local original_string=${1}
 
  # Strip off all non-numeric characters from original_string
  sanitized_string=`echo "$original_string" | sed 's/[^0-9]//g'`
 
  # Compare original_string and sanitized_string, and return a value
  if [ "$original_string" != "$sanitized_string" ]
  then
    # Invalid user input
    return 1
  else
    # Valid user input
    return 0
  fi
}
# Function #2: numeric input
 
# Function #3: alphanumeric input
validate_alphanumeric() {
 
  # User input
  local original_string=${1}
 
  # Strip off all non-alphanumeric characters from original_string
  sanitized_string=`echo "$original_string" | sed 's/[^a-zA-Z0-9]//g'`
 
  # Compare original_string and sanitized_string, and return a value
  if [ "$original_string" != "$sanitized_string" ]
  then
    # Invalid user input
    return 1
  else
    # Valid user input
    return 0
  fi
}
# Function #3: alphanumeric input
 
 
# Accept user input
echo
echo -n "  User input: "
read USER_INPUT
echo
 
# Uncomment only one of the three validations below:
# Alphabetic validation
# Note: '[ ... ]' is not a part of 'if' syntax by default;
# Using 'if [ ! validate_alphabetic "$USER_INPUT" ]' will result in errors
if ! validate_alphabetic "$USER_INPUT"
then
  echo "  Invalid (contains non-alphabetic charcaters)"
  echo
  exit
else
  echo "  Valid"
  echo
fi
 
# Numeric validation
# Note: '[ ... ]' is not a part of 'if' syntax by default;
# Using 'if [ ! validate_numeric "$USER_INPUT" ]' will result in errors
if ! validate_numeric "$USER_INPUT"
then
  echo "  Invalid (contains non-numeric charcaters)"
  echo
  exit
else
  echo "  Valid"
  echo
fi
 
# Alphanumeric validation
# Note: '[ ... ]' is not a part of 'if' syntax by default;
# Using 'if [ ! validate_alphanumeric "$USER_INPUT" ]' will result in errors.
if ! validate_alphanumeric "$USER_INPUT"
then
  echo "  Invalid (contains non-alphanumeric charcaters)"
  echo
  exit
else
  echo "  Valid"
  echo
fi
 


BASH: Smart extract

#! /bin/bash
#
# BASH script to automagically uncompress different kinds of compresed 
# files/folders based on the filename extension.
# 
# Usage:
# smart_extract.sh COMPRESSED_FILENAME
 
 
# Necessary variables
EXPECTED_ARGUMENTS=1
 
# Check if a compressed filename is supplied at the command line. If not, 
# print an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0` COMPRESSED_FILENAME"
  echo "   e.g.: `basename $0` file.tar.gz"
  echo "         `basename $0` file.zip"
  echo "         `basename $0` file.bz2"
  echo
  exit
fi
 
# Variables
COMPRESSED_FILENAME="$1"
 
# Uncompress the file based on the filename extension
if [ -f $COMPRESSED_FILENAME ]
then
  case $COMPRESSED_FILENAME in
    *.tar)
      tar -xvf  $COMPRESSED_FILENAME
    ;;
 
    *.tgz)
      tar -xvzf $COMPRESSED_FILENAME
    ;;
 
    *.tar.gz)
      tar -xvzf $COMPRESSED_FILENAME
    ;;
 
    *.tbz2)
      tar -xvjf $COMPRESSED_FILENAME
    ;;
 
    *.tar.bz2)
      tar -xvjf $COMPRESSED_FILENAME
    ;;
 
    *.gz)
      gunzip    $COMPRESSED_FILENAME
    ;;
 
    *.bz2) 
      bunzip2   $COMPRESSED_FILENAME
    ;;
 
    *.zip)
      unzip     $COMPRESSED_FILENAME
    ;;
 
    *)
      echo "  '$COMPRESSED_FILENAME' file type unknown"
    ;;
  esac
else
  echo
  echo "  '$COMPRESSED_FILENAME' is not a regular file"
  echo
fi
 


BASH: Replace space with underscore in a file name

#! /bin/bash
#
# BASH script to replace one or more spaces in file names with an underscore. 
# One may create, for testing purposes, files with space in their name as
#
#   touch "file name 1.txt"
#   touch "file name 2.txt"
#   touch "file name 3.txt"
# 
# and so on.
#
# Usage:
# replace_space_with_underscore.sh
 
 
# Necessary variables
EXPECTED_ARGUMENTS=0
 
# Check if there is any argument supplied at the command line. If yes, print 
# an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0`"
  echo
  exit
fi
 
# Loop through the list of files (use *.txt or *.dat, etc. to limit the 
# selection to specific file types) and replace space with an underscore - if 
# and only if the new file name (with underscores) does not already exist
echo
for x in *
do
  y=$(echo "$x" | tr ' ' '_')
 
  if [ -e $y ]
  then
    printf "  %25s --x--> %-25s (already exists)\n" "$x" "$y"
  else
    printf "  %25s -----> %-25s\n" "$x" "$y"
    mv "$x" "$y"
  fi
done
echo
 


BASH: Count the number of occurances of each word in a file

#! /bin/bash
#
# BASH script to count the number of occurances of each word in a specified 
# file and print the results.
# 
# If option -h is specified with any other option, -h takes precedence over 
# all other options.
#
# Usage: 
# word_count -h
# word_count.sh -F FILENAME
#
# For testing purposes, one may download a book in plain text format from 
# Project Gutenberg website using the command:
#
#   wget http://www.gutenberg.org/files/44362/44362-0.txt
 
 
# Function to display error message (help text)
show_help() {
  echo
  echo "  Usage: `basename $0` -h"
  echo "         `basename $0` -F FILENAME"
  echo
  echo "    e.g. `basename $0`"
  echo "         `basename $0` -F 44362-0.txt"
  echo
  exit
}
 
# -F must have a parameter value
# -h doesn't need a parameter value
while getopts :F:h option
do
  case "$option" in
 
    # -h
    h)
      show_help
      ;;
 
    # -F
    F)
      # If -F is specified with no value, display help
      if [ -n $OPTARG ]
      then
        FILENAME="$OPTARG"
      else
        show_help
      fi
      ;;
 
    # If nothing is specified, display help
    *)
      show_help
      ;;
 
  esac
done
 
# Validate FILENAME
# Check if FILENAME variable is empty
if [ -z $FILENAME ]
then
  show_help
fi
 
# Check if the file exists
if [ ! -e "$FILENAME" ]
then
  echo
  echo "  $FILENAME does not exit."
  echo "  Exiting."
  echo
  exit
fi
 
# Check if file has non-zero size
FILESIZE=$(du $FILENAME | awk '{ print $1 }');
if [ "$FILESIZE" -eq 0 ]
then
  echo
  echo "  $FILENAME exists but is empty."
  echo "  Exiting."
  echo
  exit
fi
 
# Check if the file has any useful information in spite of
# non-zero size
NON_BLANK_LINES=`sed '/^$/d' $FILENAME | wc -l`
if [ "$NON_BLANK_LINES" -eq 0 ]
then
  echo
  echo "  $FILENAME exists and is not empty but "
  echo "  has no useful information."
  echo "  Exiting."
  echo
  exit
fi
 
# Count the words and print to the screen
echo
echo "  --------------------------------------"
echo "    #####  Word                  Count"
echo "  --------------------------------------"
 
# egrep with the given options retains only words, numbers
# and words with numbers
egrep -o "\b[[:alnum:]]+\b" $FILENAME | \
  sort                                | \
  uniq -c                             | \
  sort -n                             | \
  awk '{ printf("    %5d  %-20s   %4d\n", NR, $2, $1); }'
 
echo "  --------------------------------------"
echo
 


BASH: List files larger than a given size in a given location

#! /bin/bash
#
# BASH script to list all files in a given directory that are equal to or 
# larger than a certain set size (expressed in MB).
# 
# If option -h is specified with any other option, -h takes precedence over 
# all other options.
#
# Usage: 
# list_file_by_size.sh -h
# list_file_by_size.sh [-l LOCATION] [-s SIZE_IN_MB]
 
 
# Function to display error message (help text)
show_help() {
  echo
  echo "  Usage: `basename $0` -h"
  echo "         `basename $0` [-l LOCATION] [-s SIZE_IN_MB]"
  echo
  echo "    e.g. `basename $0`"
  echo "         `basename $0` -s 100"
  echo "         `basename $0` -l /research/john"
  echo "         `basename $0` -l /research/john -s 10"
  echo
  exit
}
 
# -l and -s must have parameter values
# -h doesn't need a parameter value
while getopts :l:s:h option
do
  case "$option" in
 
    # -h
    h)
      show_help
      ;;
 
    # -l
    l)
      # If -l is specified with no value, display help
      if [ -n $OPTARG ]
      then
        LOCATION="$OPTARG"
      else
        show_help
      fi
      ;;
 
    # -s
    s)
      # If -s is specified with no value, display help
      if [ -n $OPTARG ]
      then
        SIZE="$OPTARG"
      else
        show_help
      fi
      ;;
 
  esac
done
 
# If SIZE is empty, then assume 2 MB limit
if [ -z $SIZE ]
then
  SIZE="2"
fi
 
# Convert size (in MB) to kB
SIZE_IN_KB=`echo "$SIZE * 1024" | bc`
 
# If LOCATION is empty, then assume present working directory
if [ -z $LOCATION ]
then
  LOCATION=`pwd`
fi
 
# Necessary variables
KILOBYTE="1024"
MEGABYTE=`echo "$KILOBYTE * 1024" | bc`
GIGABYTE=`echo "$MEGABYTE * 1024" | bc`
 
# List all files that are at least 2 MB in $LOCATION using 'find', 'awk' and
# 'sed' commands
echo
echo "  Location  : $LOCATION"
echo "  Min. size : $SIZE MB"
echo
find $LOCATION -name '*' -size +${SIZE_IN_KB}k -ls | \
  awk --assign=MB="$MEGABYTE" \
  '{ filesize+=$7; printf(" %5d MB  %s\n", $7/MB, $11); }' | \
  sort -nr
echo
 


BASH: Sum of numbers (with getopts)

#! /bin/bash
#
# BASH script to add a series of given numbers and print the sum. Works for 
# integers and non-integers alike. 'getopts' does not support "long option" 
# format (i.e., --help, --begin, --step, --end, etc.).
# 
# If option -h is specified with any other option, -h takes precedence over 
# all other options.
#
# Usage: 
# sum_numbers_getopts.sh -h
# sum_numbers_getopts.sh -B BEGIN [-S STEP] -E END
 
 
# Function to display error message (help text)
show_help() {
  echo
  echo "  Usage: `basename $0` -h"
  echo "         `basename $0` -B BEGIN [-S STEP] -E END"
  echo
  echo "    e.g. `basename $0` -B 1 -S 2 -E 100"
  echo "         `basename $0` -B 1 -E 100"
  echo
  exit
}
 
 
# The 'getopts' command is built into the BASH shell. It looks a lot like 
# 'getopt', but 'getopts' command works on the existing shell parameter 
# variables sequentially. It processes the parameters it detects in the 
# command line one at a time each time it’s called. When it runs out of 
# parameters, it exits with an exit status greater than zero. This makes it 
# suitable for using in loops to parse all of the parameters on the command 
# line. The syntax of the 'getopts' command is:
#
#   getopts optstring variable
#
# One should list valid option letters in the 'optstring', along with a colon 
# if the option letter requires a parameter value. To suppress error messages, 
# one should start the 'optstring' with a colon. The 'getopts' command places 
# the current parameter in the variable defined in the command line ('option' 
# in this case).
#
# The OPTARG environment variable contains the value to be used if an option 
# requires a parameter value. The OPTIND environment variable contains the 
# value of the current location within the parameter list where 'getopts' 
# left off. This allows one to continue processing other command line 
# parameters after finishing the options.
 
# -B, -S and -E must have parameter values
# -h doesn't need a parameter value
while getopts :B:E:S:h option
do
  case "$option" in
 
    # -h
    h)
      show_help
      ;;
 
    # -B
    B)
      # If -B is specified with no value, display help
      if [ -n $OPTARG ]
      then
        BEGIN="$OPTARG"
      else
        show_help
      fi
      ;;
 
    # -S
    S)
      # If -S is specified with no value, display help
      if [ -n $OPTARG ]
      then
        STEP="$OPTARG"
      else
        show_help
      fi
      ;;
 
    # -E
    E)
      # If -E is specified with no value, display help
      if [ -n $OPTARG ]
      then
        END="$OPTARG"
      else
        show_help
      fi
      ;;
 
    # If nothing is specified, display help
    *)
      show_help
      ;;
 
  esac
done
 
# Check to make sure that BEGIN, STEP and END have appropriate values
if [ -z $BEGIN ] || [ -z $END ]
then
  show_help
fi
 
# If STEP is empty, then assume steps of 1
if [ -z $STEP ]
then
  STEP="1"
fi
 
# Generate the sequence of numbers using 'seq'
#   Calcuate and print the sum using 'awk'
SUM=`seq $BEGIN $STEP $END | \
       awk '{ sum += $1 } END { print sum }'`
 
# Print to screen
echo
echo "  Begin (-B) : $BEGIN"
echo "  Step  (-S) : $STEP"
echo "  End   (-E) : $END"
echo "  Sum        : $SUM"
echo
 


BASH: Sum of numbers

#! /bin/bash
#
# BASH script to add a series of given numbers and print the sum. Works for 
# integers and non-integers alike.
#
# Usage: 
# sum_numbers.sh BEGIN [STEP] END
 
 
# Necessary variables
MINIMUM_ARGUMENTS=2
MAXIMUM_ARGUMENTS=3
 
# Check if the user has supplied less than the minimum OR more than the 
# maximum number of arguments at the command line. If yes, print an error 
# message (help text) and exit
if [ $# -lt $MINIMUM_ARGUMENTS ] || [ $# -gt $MAXIMUM_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0` BEGIN [STEP] END"
  echo "   e.g.: `basename $0` 1 1 10"
  echo "         `basename $0` 1 2 10"
  echo "         `basename $0` 1 10"
  echo
  exit
fi
 
# If the third argument is missing, then assume increments of 1
if [ -z $3 ]
then
  BEGIN="$1"
  STEP="1"
  END="$2"
else
  BEGIN="$1"
  STEP="$2"
  END="$3"
fi
 
# Generate the sequence of numbers using 'seq'
#   Calcuate and print the sum using 'awk'
SUM=`seq $BEGIN $STEP $END | \
       awk '{ sum += $1 } END { print sum }'`
 
# Print to screen
echo
echo "  Begin : $BEGIN"
echo "  Step  : $STEP"
echo "  End   : $END"
echo "  Sum   : $SUM"
echo
 


BASH: Login counter

#! /bin/bash
#
# BASH script to count and display usernames in descending order of the number 
# of successful login attempts.
#
# Usage:
# login_counter.sh
 
 
# Necessary variables
EXPECTED_ARGUMENTS=0
 
# Check if there is any argument supplied at the command line. If yes, print 
# an error message (help text) and exit
if [ $# -ne $EXPECTED_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0`"
  echo
  exit
fi
 
# Date/Time when the record keeping began
#  System's own record of login attempts using 'last'
#  Ignore everything but the very last line using 'tail'
#  Select the last field (date and time) using 'awk' with 
#    "wtmp begins " as the field separator
RECORD_START_DATE=`last      | \
                     tail -1 | \
                     awk -F 'wtmp begins ' '{ print $NF }'`
 
# Print to the screen
echo
echo "  Hostname   : `hostname`"
echo "  Start date : $RECORD_START_DATE"
echo 
#   System's own record of login attempts using 'last'
#   Delete all blank lines using 'sed'
#   Ignore all lines that contain 'wtmp'
#   Select the first field (username) using 'awk' using 
#     space as the field separator
#   Sort the first column using 'sort'
#   Count the number of duplicate lines using 'uniq'
#   Reverse sort the list using 'sort' to get the 
#     descending order
last                        | \
  sed '/^$/d'               | \
  grep -v "wtmp"            | \
  awk -F ' ' '{ print $1 }' | \
  sort                      | \
  uniq -c                   | \
  sort -nr
echo
 


BASH: Hello, User!

#! /bin/bash
#
# BASH script to print "Hello, USERNAME!" to the screen, along the hostname, 
# current date/time and current working directory. USERNAME is the username 
# of currently logged in user.
# 
# Usage:
# hello_user_regular.sh
 
 
# Print to the terminal
echo
echo "  Hello, $USER!"
echo "  Hostname  : `hostname`"
echo "  Date/Time : `date -R`"
echo "  Location  : `pwd -P`"
echo
 



#! /bin/bash
#
# BASH script to print "Hello, USERNAME!" to the screen, along with the 
# hostname and current date/time iff a username is supplied at the command 
# line.
# 
# Usage:
# hello_user_special.sh USERNAME
 
 
# Necessary variables
EXPECTED_ARGUMENTS=1
 
# Check if the username is supplied at the command line. If not, print an 
# error message (help text) and exit
if [ $# -ne $EXPECTED_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0` USERNAME"
  echo "   e.g.: `basename $0` john"
  echo
  exit
fi
 
# Variables
USERNAME="$1"
 
# Print to the terminal
echo
echo "  Hello, $USERNAME!"
echo "  Hostname  : `hostname`"
echo "  Date/Time : `date -R`"
echo
 



#! /bin/bash
#
# BASH script to print "Hello, USERNAME!" to the screen, along with the 
# hostname and current date/time. USERNAME is the username supplied at the 
# command line; if not supplied, use the currently logged in user's username.
# 
# Usage:
# hello_user_premium.sh [USERNAME]
 
 
# Necessary variables
MAXIMUM_ARGUMENTS=1
 
# Check if more than the maximum number of arguments have been supplied at the 
# command line. If yes, print an error message (help text) and exit
if [ $# -gt $MAXIMUM_ARGUMENTS ]
then
  echo
  echo "  Usage: `basename $0` [USERNAME]"
  echo "   e.g.: `basename $0` john"
  echo "         `basename $0`"
  echo
  exit
fi
 
# Check if the username is supplied at the command line. If yes, set USERNAME 
# to supplied value; if not, set it to username of currently logged in user
if [ $# -eq $MAXIMUM_ARGUMENTS ]
then
  USERNAME="$1"
else
  USERNAME="$USER"
fi
 
# Print to the terminal
echo
echo "  Hello, $USERNAME!"
echo "  Hostname  : `hostname`"
echo "  Date/Time : `date -R`"
echo