Bash utilities (part 2): Bash programming

Several cheat-sheets of different topics in .md format. Checkout the Github pages version.

Bash utilities (part 2): Bash programming

Redirect stderr and stdout to trash

Only stderr

2>/dev/null  

Only stdout

1>/dev/null

Both stderr and stdout

2> /dev/null 1>&2

If statement

Check if input is empty

if [ -z $1 ]
then
 ...
fi

Check number of input arguments

if [ "$#" -ne 1 ]; then
    echo "Illegal number of parameters"
fi

Check if a file exists:

exists=$( 2>/dev/null ls ${MAINDIR}/${TFFILE} )
if [ -z "${exists}" ]
then
  echo "File ${MAINDIR}/${TFFILE} does not exists"
else
 ...
fi

Compare two integers:

if (( a > b )); then
    ...
fi
# or
if [ "$a" -gt "$b" ]; then
    ...
fi

Arrays

Declare arrays

x=();
y=("anr" "123" "asd");

Access to specific elements

echo "${y[0]}" "${y[2]}" "${y[-1]}" "${y[-2]}"

Access to all the elements

echo "${y[@]}"

Loop over all the elements

for i in "${y[@]}"
do
 ...
done

also, to loop over integer values:

for i in {1..32}
do
 ...
done

or in one line

for i in {1..90}; do; echo "" > file-$i.txt ; done

Append an element to existing array

array+=new_element

Create a new array copying an existing one

newArray=( "${oldArray[@]}" )

Print the number of elements of an array

echo "${#array[@]}"

Associative arrays, or arrays with keys-value pairs, example of dynamic creation from file:

declare -A REPOSITORIES
for rpt in `cat "${repositories_file}" | grep -v '#'`; do
	rpt_name=`echo ${rpt} | awk -F: '{print $1}'`
	rpt_flag=`echo ${rpt} | awk -F: '{print $2}'`
	AAT_REPOSITORIES+=(["${rpt_name}"]="${rpt_flag}")
done

Another example:

declare -a myArray

myArray[a]=123
myArray[b]=343
myArray+=([c]=345 [c]=054)

Access the keys:

for key in "${!array[@]}"; do
...
done

echo "${!array[@]}

Access the values:

echo ${myArray[a]}
echo ${myArray[@]}

Functions

Example of declaring a function called “fun”

fun () {
 echo "Hello World! My name is $1 and I like $2"
}

so that, we invoke it as follows:

fun "Peter" "bash programming"

Split a string using a delimiter

Function that splits a string and stores elements splitted in an array

func_splitter() {
  str=$1
  delimiter=$2
  s=$str$delimiter
  array=();
  while [[ $s ]]; do
      array+=( "${s%%"$delimiter"*}" );
      s=${s#*"$delimiter"};
  done;  
}

Call it to split a string using a specific delimiter, like -, as follows

func_splitter "$string" "$delimiter"
echo "${array[@]}"

Simply split a string in two parts

partLeft=${string%%"$delimiter"*}
partRight=${string#*"$delimiter"}

Store stdout in a variable

Examples

var1=$(echo ls -lrt)
var2=$(cat file.log)

String manipulation

Check if a string contains only alphanumeric and {“-”, “_”} characters.

if [[ "${ENVNAME}" =~ ^[a-zA-Z0-9_-]+$ ]]
then
  echo "${ENVNAME}"
else
  echo "${ERRMSSGA}"
  exit
fi

Read a string line by line:

#!/bin/bash
while IFS= read -r line
do
  echo "$line"
done <<< "${string}"

Read a file line by line:

#!/bin/bash
while IFS= read -r line
do
  echo "$line"
done < "${pathToFile}"

Replace a string substring by a new one

string="a new new test"
substring="new"
newone="old"
echo "${string/$substring/$newone}" 

Replace all occurrences in a string of a substring by a new one

message='The secret key is 431241'
echo "${message//[0-9]/X}"           
# prints 'The secret key is XXXXX'

Remove white spaces

var=$(echo "${var}//[:blank:]]/")

Remove all control characters:

var=${var//[ $'\001'-$'\037']}

Transform string to integer after removing control characters

expr $string
num1=$((string + 0))
num2=$((stra + strb))

Modify using patterns

string=str1_str2_str3.str4.str5
echo ${string##*_} # removes largest occurence of pattern at the begginning of string
echo ${string#*_} # removes smallest occurence of pattern at the begginning of string
echo ${string}
echo ${string%.*} # removes smallest occurence of pattern at the end of string
echo ${string%%.*} # removes largest occurence of pattern at the end of string
echo ${string/.*/repl01} # replaces first occurrence of pattern in string
echo ${string//.*/repl01} # replaces all occurrences of pattern in string

Get script file name inside script

script_name=`basename "$0"`

Locate repository absolute path (under home)

At the root of the repository, create a unique dummy file.

For example, if the repository is named “etl”, the dummy file could be .etl.dir.

Next, in the script code, the repository absolute path can be found with:

repo_dir=`find ${HOME} -name ".etl.dir" -type f -print -quit`
repo_dir=${script_dir%/*}

File manipulation

Replace all “word” occurencies by “new” in all file “FILE”

sed -i -e "s/word/new/g" FILE

Remove lines from a file that contain a substring

while read line; do
  [[ ${line} != *"RISK SCORE"* ]] && echo "$line" >> ${temp}
done < $outputData

Date-Time stamp

Store current date-time stamp in a variable

dtimestamp=$( echo "$(date +'%Y%m%d-%H_%M_%S_%3N')" )

Add timestamp to echo’s with a log format:

timestamp () {
    echo "[`date +'%Y-%m-%d %H:%M:%S'`]"
}

echo "$(timestamp) Some log message."

Miscellaneous

Verify number of occurrences in a set of files:

files=(
   "./*.csv"
)

for file in ${files}
do
   I103=$(cat ${file} | grep -c '{2:I103')
   O103=$(cat ${file} | grep -c '{2:O103')
   nI103=$((I103+0))
   nO103=$((O103+0))
   ntotalMT103=$((nI103+nO103))
   total=$(cat ${file} | grep -c '\$')
   ntotal=$((total+0))
   if [ ${ntotal} -eq ${ntotalMT103} ] 
   then
      echo    
      echo ${file}
      echo '  'number of 103 occurrences in file: ${ntotalMT103}
      echo '  'total number of symbol occurrences in file: ${ntotal}
   fi
done

Return to bash - part 1

Return to main page