Script#
Tutorials/Links#
Creating a Script#
First, create a file with the *.sh
extension.
Next, open your script and put the following at the top:
#!/bin/bash
Arrays#
Create array from list of files
FILES=($(ls -r data*.*))
Use array (just an example)
${FILES[2]}
Strings#
Get the first 2 characters of a string
my_string="hola"
echo ${my_string:0:2}
Get the last 2 characters of a string
echo ${my_string: -2}
Remove the first character of a string
echo ${my_string:1}
Remove the last 2 characters of a string
echo ${my_string%??}
Display the first line where a pattern is found (here dim3), and remove the first characters that matches a given string
fslhd t1w.nii.gz | grep -m 1 dim3 | sed -e "s/^dim3 //"
Batch actions with grep
`grep` is powerful for creating an action based on a series of input (e.g. multiple files). Below is an example to delete several branches in git, based on their prefix name:
git branch -D `git branch | grep -E 'BRANCH_PREFIX*'`
Check if substring is in string
my_string='My long string'
if [[ $my_string == *"My long"* ]]; then
echo "It's there!"
fi
More info here: http://tldp.org/LDP/abs/html/string-manipulation.html
Dates#
To list the date every week for the next five weeks, starting in 2 days:
for i in {1..5}; do echo $(date -v +${i}w -v +2d "+%Y-%m-%d"); done
FOR Loop#
Loop across list elements
ARRAY=(element1 element2 element3)
for i in ${ARRAY[@]}; do
echo $i
done
Loop across list elements (using indices)
ARRAY=(element1 element2 element3)
for i in ${!ARRAY[@]}; do
echo "Element: $((i+1))/${#ARRAY[@]}"
echo ${ARRAY[$i]}
done
**Loop across numerical range (with zero filling)
START=30
END=150
for i in $(seq -f "%03g" $START $END); do
echo $i
done
Loop across an array of strings
SUBJECT_LIST=(subject_a subject_b)
for subject in ${SUBJECT_LIST[@]}; do
echo $subject
done
Loop across a series of files
for filename in im1 im2 im3 ; do
bet $filename ${filename}_brain ;
done
Using ls
FILES=`ls folder/*.nii`
for file in $FILES; do
echo $file
done
Do it in a single line:
FILES=`ls folder/*.nii`; for file in $FILES; do echo $file; done
Using find (recursive)
FILES=`find . -name *.nii`; for file in $FILES; do echo $file; done
IF Statements#
IF - AND#
if [ ! -z "$var" ] && [ -e "$var" ]; then
do something ...
else
do something else...
fi
alternative:
[ ! -z "$var" -a -e "$var" ]
IF - OR#
if [[ "$s1" == "$s2" ]]; then
do something...
fi
if [ ! -z "$var" ] || [ -e "$var" ]; then
do something ...
fi
alternative:
[ ! -z "$var" -o -e "$var" ]
CSV Files#
Parse CSV File#
while IFS=, read col1 col2 col3 col4 col5
do
echo "$col2"
done < <FILE>.csv
Command Line Input#
#!/bin/bash
# use predefined variables to access passed arguments
# echo arguments to the shell
echo $1 $2 $3 ' -> echo $1 $2 $3'
# list all arguments:
echo $@
# We can also store arguments from bash command line in special array
args=("$@")
# echo arguments to the shell
echo ${args[0]} ${args[1]} ${args[2]} ' -> args=("$@"); echo ${args[0]} ${args[1]} ${args[2]}'
# use $@ to print out all arguments at once
echo $@ ' -> echo $@'
# use $# variable to print out number of arguments passed to the bash script
echo Number of arguments passed: $# ' -> echo Number of arguments passed: $#'
Log Files#
Generate log file #
LOGFILE=<FILE_NAME>.log
{
# bash commands...
} 2>&1 | tee $LOGFILE
Generate a log file of a script directly in terminal:
script.$$ [options] | tee <FILE_NAME>.log
Add date to log file: log_file_name_$(date +%Y%m%d).logEdit
Colors#
The Mountain Lion Terminal does not support the command echo -e
therefore the following has to be used:
printf "\e[0;32mText here\e[0m"
ANSI Escape Codes for Colours#
Colour |
ANSI Escape Code |
---|---|
Black |
0;30 |
Red |
0;31 |
Green |
0;32 |
Brown/Orange |
0;33 |
Blue |
0;34 |
Purple |
0;35 |
Cyan |
0;36 |
Light Grey |
0;37 |
Yellow |
1;33 |
White |
1;37 |
No Colour |
0 |
BLACK='\033[0;30m'
RED='\033[0;31m'
NC='\033[0m'
Misc#
Pass argument from file
mycommand "$(< file.txt)"
Test existence of a file
if [ -e "$var" ]; then