Skip to content

Instantly share code, notes, and snippets.

@vuiseng9
Last active December 17, 2020 23:15
Show Gist options
  • Save vuiseng9/5506d23c9bd4db6eb1e44bd3b6eb6372 to your computer and use it in GitHub Desktop.
Save vuiseng9/5506d23c9bd4db6eb1e44bd3b6eb6372 to your computer and use it in GitHub Desktop.
my favourite bash routines

Quick Guide - Bash Scripting

Mar'19, vuiseng9

The Shebang

#!/usr/bin/env bash

/bin/bash # for docker entrypoint

Basename of filepath

filepath=/abc/xyx/myfile.tar.gz

# seperate directory path and filename
dir=$(dirname ${filepath})
file=$(basename ${filepath})
echo "dir: ${dir}, file: ${file}"
# fullpath=$(realpath ${filepath})
# fulldir=$(dirname ${fullpath})

# strip preceding directory and remove the extension
base=$(basename ${filepath} .tar.gz)
echo $base

# if you dont know the extension upfront
# 1. strip from 1st period
base=$(basename ${filepath})
base=${base%%.*}
echo $base

# 2. strip from last period
base=$(basename ${filepath})
base=${base%.*}
echo $base

# or simple string extension replacement
filepath=foo/bar/hello.txt
newfile=${filepath/txt/md}

if file/folder exists

if [ -f ~/.bashrc ]
then
  echo "File ~/.bashrc exist"
fi

if [ ! -d /folder_not_exist ]
then
  echo "Folder doesn't exist."
else
  echo "Folder exists."
fi

Recursively traverse directory (similar to python os.walk)

function traverse() {
for file in "$1"/*
do
    if [ ! -d "${file}" ] ; then
        echo "${file} is a file"
    else
        echo "entering recursion with: ${file}"
        traverse "${file}"
    fi
done
}

Loop with counter

# 1. for style
for ((i=0; i<=10; i++))
do
  echo ${i}
done

# 2. While style
# note that space is required after [ and before ]
i=0
while [ $i -lt 10 ]
do
  echo ${i}
  i=$(($i+1))
done

Loop files

You dont need glob like python

for filename in *.txt
do 
  echo ${filename}
done

Loop list of Literals

for d in 0.01 hello candle9
do 
  echo $d
done

Associative Array as list

declare -a array=(one two three)

# print all indices
echo ${!array[@]}

# print all elements
echo ${array[@]}

# get length of an array
echo ${#array[@]}

# loop element
for element in ${array[@]}
do
  echo ${element}
done

# loop list with index
for i in ${!array[@]}
do
  echo "array[$i] = ${array[$i]}"
done

# loop with for loop
for ((i=0; i<${#array[@]}; i++));
do
  echo "array[$i] = ${array[$i]}"
done

Associative Array as key-value store

declare -A fruits
fruits[a]=apple
fruits[b]="berry"
fruits["c"]=cherry

# print all keys
echo ${!fruits[@]}

# print all values
echo ${fruits[@]}

# use hash to get count of value entry
echo ${#fruits[@]}

# loop key
for key in ${!fruits[@]}
do
  echo "key: $key <=> value: ${fruits[$key]}"
done

Functions in Bash

$@ for all arguments, $1, $2 ... to specify individual argument

# Vertical/Columnar aligned less on csv
function pretty_csv {
    column -t -s, -n "$@" | less -F -S -X -K
}

function set_gpu {
    export CUDA_VISIBLE_DEVICES=$1
    get_gpu
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment