Bash

nano filename.sh
  #!/bin/bash
  myscriptcontent
chmod u+x filename.sh

Associative Arrays

https://clubmate.fi/associative-arrays-in-bash/

declare -A names=(
[caleb]=sargeant
[network]=guru
)

for i in "${!names[@]}"
do
  first_name=$i
  last_name=${names[$i]}
  echo "$first_name : $last_name"
done

Getopt

# Execute getopt for arguments to be passed to script, identified by "$@"
PARSED_OPTIONS=$(getopt -n "$0" -o hfi: --long "help,file,input:" -- "$@")

# Bad arguments or something wrong with getopt
if [ $? -ne 0 ]; then
  exit 1
fi

# getopt juju
eval set -- "$PARSED_OPTIONS"

# go through each option and use shift to analyse 1 argument at a time, discarding $1, making $2 $1, etc.
while true;
do
  case "$1" in
    -h|--help)
      echo "usage $0 -h -f -i or $0 --help --file --input"
      shift;;

    -f|--file)
      echo "file"
      shift;;

    -i|--input)
    echo "input"

      if [ -n "$2" ]; then
        echo "Arguement: $2"
      fi
      shift 2;;

    --)
    shift
    break;;
  esac
done

Usage

usage() {
printf "Usage: "$0" <region> \n
        Regions available:
        SA\t(South Africa)
        UK\t(United Kingdom)
        US\t(United States)\n\n" 1>&2;
        }

case $1 in
  (SA|UK|US) ;;
  #unhash the next line - it's just messing with RST
  #(*) usage
esac

if [ "$1" == "SA" ]; then
  export MYVAR="varSA"
elif [[ "$1" == "UK" ]]; then
  export MYVAR="varUK"
elif [[ "$1" == "US" ]]; then
  export MYVAR="varUS"
fi

Functions

function() {
  echo $@
}

# function accepts positional parameters via $@

sed

# Removes all comments including those with tabs and spaces
sed -e '/^[ \t\n]*#/d'

# Replacing Text (in this case remove ")
sed 's/"//g'

# Delete first line
sed -i -e 1d

awk

# Print the first column using "," as separator
awk -F "," '{print $1}'

cut

# Remove the filename extension (eg. ".exe")
name=$(echo "$filename" | cut -f 1 -d '.')

Prompt for Input

Using read

  • Simple & common

while true; do
  read -p "Do you wish to install this program?" yn
    case $yn in
      [Yy]* ) make install; break;;
      [Nn]* ) exit;;
    * ) echo "Please answer yes or no.";;
  esac
done

Using select

  • No need to sanitize input

  • Prompts you with choice you want

  • Automatically loops (no need for while true loop to retry)

echo "Do you wish to install this program?"
select yn in "Yes" "No"; do
  case $yn in
    Yes ) make install; break;;
    No ) exit;;
  esac
done

Output Formatting

Source for more formatting options: http://misc.flogisoft.com/bash/tip_colors_and_formatting

echo -e "\e[1mbold\e[0m"
echo -e "\e[3mitalic\e[0m"
echo -e "\e[4munderline\e[0m"
echo -e "\e[9mstrikethrough\e[0m"
echo -e "\e[31mHello World\e[0m"

For Loops

Loop through directory names https://unix.stackexchange.com/questions/86722/how-do-i-loop-through-only-directories-in-bash

for d in */ ; do
  echo "$d"
done

Loop through file names https://stackoverflow.com/questions/10523415/execute-command-on-all-files-in-a-directory

for file in /dir/* ; do
    cmd [option] "$file" >> results.out
done

Arithmetic

Bash is limited to integer math

Sum

Adding all numbers from output

https://stackoverflow.com/questions/450799/shell-command-to-sum-integers-one-per-line

awk '{sum+=$0} END{print sum}'

Divide

https://stackoverflow.com/questions/1088098/how-do-i-divide-in-the-linux-console

x=10
y=5

# Don't enclose variables in quotes this time
$ echo $(( $x / $y ))
2

Scientific Notation & Rounding

https://stackoverflow.com/questions/8356698/how-to-remove-decimal-from-a-variable https://unix.stackexchange.com/questions/104332/remove-scientific-notation-bash-script

# Round & remove scientific notation (0f is the number of decimals)
$ echo 2.123456 | awk '{ print sprintf("%.0f", $1); }'
2

# Round down
$ printf %.0f 1.89
2

Incrementing

$ echo $((n=n+1))
1
$ echo $((n=n+1))
2

wc

Number of Lines

wc -l myfile.txt

Number of Words

wc -w myfile.txt

Number of Characters

wc -m myfile.txt

pwd

https://stackoverflow.com/questions/1371261/get-current-directory-name-without-full-path-in-a-bash-script

# Get current working directory as variable in bash
$ result=${PWD##*/}
$ echo $result
caleb.sargeant

# Using basename
$ pwd
/Users/caleb.sargeant
$ basename $(pwd)
caleb.sargeant

https://stackoverflow.com/questions/8426058/getting-the-parent-of-a-directory-in-bash

dir=/home/caleb.sargeant/Desktop/Test
parentdir="$(dirname "$dir")"

tr

$ echo __ | tr _ -
--

if

Check if a file type exists in directory https://stackoverflow.com/questions/3856747/check-whether-a-certain-file-type-extension-exists-in-directory

count=$(ls -1 *.json 2>/dev/null | wc -l)
if [ $count != 0 ]; then
  echo true
fi

Check if variable not set

if [[ -z "$REGION" ]]; then
  echo "$REGION not set"
  exit 1
fi

Search for Text in Files

grep -rnw '/etc/' -e 'NULL'

Extract Text Before Character

https://stackoverflow.com/questions/20348097/bash-extract-string-before-a-colon

# Replace colon with whatever:
cut -d: -f1
# or
awk -F: '{print $1}'
# or
sed 's/:.*//'

History

https://unix.stackexchange.com/questions/212872/how-to-get-last-n-commands-from-history

# Where n is the number of lines you want to "tail":
history n