Table of Contents
Bash Variable String Manipulation
A = "123456" # This prints the chars from 3 to 5 # Chars are counting from [0] echo ${A:3:5} # prints "456" echo ${A:1:4} # prints "2345" # Prints the number of chars echo ${#A} # prints "6"
Front Match
These are the examples of a front matching
Front is meant to be “left to right” matching
a = "blog.gryzli.info" echo ${a#*.} # prints "gryzli.info" echo ${a##*.} # prints "info"
Rear Match
These are the examples of a rear matching
Front is meant to be “right to left” matching
a = "blog.gryzli.info"
echo ${a%.*}
# prints "blog.gryzli"
echo ${a%%.*}
# prints "blog"
String substitution
stringZ=abcABC123ABCabc
echo ${stringZ/abc/xyz} # xyzABC123ABCabc
# Replaces first match of 'abc' with 'xyz'.
echo ${stringZ//abc/xyz} # xyzABC123ABCxyz
# Replaces all matches of 'abc' with # 'xyz'.
Remove Suffix From String
string="domain.com"
# Prints "domain"
echo ${string%.com}
BASH Arrays
One-dimensional arrays
- Define array:
array=(x y z)
- Print element from array:
# Prints "x" echo ${array[0]} # Prints "z" echo ${array[2]}
- Print the number of elements in array:
# Prints 3 echo ${#array[*]}
- Check if array value exists
# Check if key '4' exists in this array key=4 [ ${array[$key]+abc} ] && echo "Key $key exists"
Adding value to array without specifying index (array push/unshift)
This could be done by the following syntax:
GRYZ_ARR=()
GRYZ_ARR+=('value1')
GRYZ_ARR+=('value2')
This will add values “value1” and “value2” to the array: GRYZ_ARR
Working with associative arrays in BASH
Declare associative array
Here it’s very important to use the “declare -A array_name” notation in order to define working associative array. After the array is defined you can use different methods to fulfill it with elements.
# First declare that this is associative array declare -A some_array # Now define array elements some_array=( [key1]=value1 [key2]=value2 [key3]=value3 ) # OR some_array[key1]=value1 some_array[key2]=value2 ....etc
Iterate through associative array
Now that we have our array defined and fulfilled, we can try to iterate through it’s keys and print it’s values.
# Iterate through array: some_array for key in "${!some_array[@]}"; do # Print the key:value pair echo "Key: $key, Value: ${some_array[$key]}" done
Bash Arithmetic
If you need to make some arithmetics, here are some tools you could use:
Using bc
Basic Calculator (bc) is a mathematical scripting language with a syntax similiar to C.
If you want to sum floating numbers:
a=0.22; b=1.11 sum=$(echo "$a + $b" | bc ) # Sum = 1.33
Using expr
expr is another basic command which could be used to evaluate basic expressions.
Here are some examples
echo $(expr 5 + 5) # Result "10" echo $(expr 5 * 5) # Result "25" echo $(expr 5 % 3) # Result "2"
Using let
number=5 let "number--" # $number is 4 let "number++" # $number is 5 again let "sum = number + 5" # $sum is 10
Unsorted tips and tricks
find on same filesystem
Find files and directories, without descending from the finding filesystem.
# -xdev disables find of descending to another filesystem find / -xdev
Check if variable is empty
if [ -n $test_var ]; then echo "$test_var is not empty" fi
Get Symlink destination path
If you want to check the destination of a given symlink, this could be done, by using the command: readlink . The command is part of the “coreutils” packages, so there is a very big chance, to have it already installed.
# First let's create some symlink ln -s /root/some_existing_file /root/symlink_to_file # Now get the destination of the symlink file readlink /root/symlink_to_file # Result: # /root/some_existing_file # readlink exit code: 0 # If we execute readlink command over NOT SYMLINK file # then we will get empty result and exit code "1"
Random Sleep
Implementing random sleep from 0 to XXXX seconds
# Sleep some random time from 0 to 5555 seconds sleep $[ 1 + $[ RANDOM % 5555 ]]
Code blocks
{ read row1 read row2 } < /path/to/some/file
{ echo 1 echo 2 echo 3 } > /path/to/file # cat /path/to/file # 1\n2\n3\n
Brace expansion
echo \"{These,words,are,quoted}\" # "These" "words" "are" "quoted" cp my_file.{txt,bkp} # Copies "my_file.txt" to "my_file.bkp" echo {a..z} # a b c d e f g h i j k l m n o p q r s t u v w x y z # Echoes characters between a and z. echo {0..3} # 0 1 2 3 # Echoes characters between 0 and 3.
Integer expansion
a=3 b=7 echo $[$a+$b] # 10 echo $[$a*$b] # 21 test=$(( 1 + 3 )) # $test is 4
Print formated columns output
This will issue printf for every line it gets from the $() command. This way it will print well bounded columns.
! Do not use this for very big files, cause the the “argument” will overflow !
printf "%14s %14s %14s %14s %14s\n" $(cat some_text_file.txt)
BASH Modifying Bash Script During Execution
Recently I found some weird behavior of BASH, which will let you append code to bash script, during it’s execution, and the code will get executed as well.
In order to materialize what I mean, here is the nasty example:
gryzli@localhost [~/temp]$ cat test.sh #!/bin/bash echo 'echo "THIS WILL BE APPENDED AND EXECUTED"' >> $0 gryzli@localhost [~/temp]$ bash test.sh THIS WILL BE APPENDED AND EXECUTED gryzli@localhost [~/temp]$ cat test.sh #!/bin/bash echo 'echo "THIS WILL BE APPENDED AND EXECUTED"' >> $0 echo "THIS WILL BE APPENDED AND EXECUTED"
BASH Escaping Quotes
In bash you are able to escape only double-quotes inside double quotes.
Example (This is okay):
gryzli@localhost [~/temp]$ echo "Escaping is \"working\"" Escaping is "working"
You CAN’T escape single quotes inside single quotes
Example (This is NOT):
# This breaks and shell is waiting for input gryzli@localhost [~/temp]$ echo 'Escaping is \'NOT\' working ' >
REFERENCES
One of the best places to learn BASH for me is TLDP:
http://tldp.org/LDP/abs/html/abs-guide.html
bugbear