Variable Deletion and Replacement
Removing Prefix Patterns
Removing the shortest matching prefix pattern using #:
greeting="Hello World, Welcome to Shell"
echo $greeting
greeting_clean=${greeting#*or}
echo $greeting_clean
Removing the longest matching prefix pattern using ##:
greeting_long=${greeting##*or}
echo $greeting_long
String Substitution
Replace only the first occurrence using single /:
echo $PATH
modified_path=${PATH/sbin/SBIN}
echo $modified_path
Replace all occurrences using double //:
global_replace=${PATH//sbin/SBIN}
echo $global_replace
Variable Testing
Simple variable substitution with default values (less commonly used):
result=${input_expr-default}
If input_expr is undefined, result receives default. If input_expr has a value, result takes that value.
String Processing
Calculating String Length
Method 1 - Using parameter expansion:
length=${#sample}
echo $length
Method 2 - Using expr command:
length_val=`expr length "$sample_text"`
echo $length_val
Finding Substring Index Position
The index function splits the string into characters and returns the position of the first matching character:
sentence="programming is interesting"
pos=`expr index "$sentence" ing`
echo $pos
When searching for a nonexistent substring, it returns 1:
pos=`expr index "$sentence" xyz`
echo $pos
Matching Substring Length
Matches from the beginning (returns 0 if not found):
text="programming is interesting"
matched_len=`expr match "$text" interesting`
echo $matched_len
Matching from the start with wildcards:
matched_len=`expr match "$text" prog.*`
echo $matched_len
Substring Extraction
Method 1 - Extract from position to end (0-based indexing):
data="spark hadoop flink storm"
extracted=${data:10}
echo $extracted
Method 2 - Extract specific length from position:
extracted=${data:10:5}
echo $extracted
Method 3 - Extract last 5 characters:
extracted=${data: -5}
echo $extracted
Method 4 - Alternative syntax with parentheses:
extracted=${data:(-5)}
echo $extracted
Method 5 - Extract first 2 characters of the last 5:
extracted=${data: -5:2}
echo $extracted
Important: When using expr, indices start at 1. When using ${string:position}, indices start at 0.
Complete String Processing Script
Requirement:
Given: data="Data processing framework is Spark,Spark is a distributed computing system"
Create a menu-driven script that:
- Displays the string value
- Option 1: Print string length
- Option 2: Remove all occurrences of "Spark"
- Option 3: Replace first "Spark" with "Flink"
- Option 4: Replace all "Spark" with "Flink"
- Exit when user inputs
qorQ
Implementation Plan:
- Define functions for each operation:
show_menucalculate_lengthremove_sparkreplace_firstreplace_all
Functions Implementation:
#!/bin/bash
#
data="Data processing framework is Spark,Spark is a distributed computing system"
show_menu()
{
echo "********************************"
echo "(1) Show string length"
echo "(2) Remove all Spark occurrences"
echo "(3) Replace first Spark with Flink"
echo "(4) Replace all Spark with Flink"
echo "********************************"
}
calculate_length()
{
echo "${#data}"
}
remove_spark()
{
echo "${data//Spark/}"
}
replace_first()
{
echo "${data/Spark/Flink}"
}
replace_all()
{
echo "${data//Spark/Flink}"
}
Main Script Logic:
#!/bin/bash
#
data="Data processing framework is Spark,Spark is a distributed computing system"
show_menu()
{
echo "********************************"
echo "(1) Show string length"
echo "(2) Remove all Spark occurrences"
echo "(3) Replace first Spark with Flink"
echo "(4) Replace all Spark with Flink"
echo "********************************"
}
calculate_length()
{
echo "Length: ${#data}"
}
remove_spark()
{
echo "${data//Spark/}"
}
replace_first()
{
echo "${data/Spark/Flink}"
}
replace_all()
{
echo "${data//Spark/Flink}"
}
while true
do
echo " [data=$data]"
echo
show_menu
read -p "Enter choice (1|2|3|4|q|Q):" choice
case $choice in
1)
calculate_length
;;
2)
remove_spark
;;
3)
replace_first
;;
4)
replace_all
;;
q|Q)
exit
;;
*)
echo "Invalid input. Use 1|2|3|4|q|Q"
;;
esac
done
Command Substitution
Syntax
Command substitution captures command output into variables.
Example 1: List All System Users
Extract usernames by cutting the first field from /etc/passwd:
cat /etc/passwd | cut -d ":" -f 1
Using a loop (space, newline, and tab serve as delimiters):
#!/bin/bash
#
counter=1
for username in `cat /etc/passwd | cut -d ":" -f 1`
do
echo "User #$counter: $username"
counter=$(($counter + 1))
done
Example 2: Calculate Years
echo "Current year: $(date +%Y)"
echo "Next year: $(( $(date +%Y) + 1))"
Summary: Backticks (`) and $() are equivalent, though $() is recommended for clarity. The $() syntax is slightly less portable but widely supported. Backticks work on all POSIX systems. $(()) performs integer arithmetic, and $ before variable names is optional.
Integer operations:
echo "$((50 + 30))"
echo "$(( (80 + 40) / 12 ))"
num1=100
num2=50
echo "$((num1 + num2))"
Example 3: Day of Year Calculations
echo "Today is day $(date +%j) of the year"
echo "Weeks passed: $(($(date +%j) / 7))"
echo "Days remaining: $((365 - $(date +%j)))"
echo "Weeks remaining: $(((365 - $(date +%j)) / 7))"
Example 4: Process Monitoring
Check if nginx is running, start if not:
#!/bin/bash
#
# Exclude the grep process itself
nginx_count=$(ps -ef|grep nginx|grep -v grep|wc -l)
if [ $nginx_count -eq 0 ]; then
systemctl sttart nginx
fi
Typed Variables
Shell supports type declarations using declare.
Read-only Variables
readonly_var="immutable value"
declare -r readonly_var
readonly_var="new value" # This will fail
Integer Variables
By default, variables are treated as strings:
val1=100
val2=$val1+50
echo $val2 # Output: 100+50
Declaring as integer:
declare -i val3
val3=$val1+200
echo $val3 # Output: 300
Arrays
Declaring and initializing:
declare -a fruits
fruits=("apple" "banana" "orange" "grape")
Accessing elements:
echo ${fruits[@]} # All elements
echo ${fruits[1]} # Second element
echo ${#fruits[@]} # Array length
echo ${#fruits[0]} # Length of first element
Function and Variable Listing
declare -f # Show all functions with definitions
declare -F # Show function names only
Common Array Operations
items=("cat" "dog" "bird" "fish")
# Display all element
echo ${items[@]}
# Access specific index
echo ${items[2]}
# Get array length
echo ${#items[@]}
# Get element length
echo ${#items[1]}
# Assign to specific index
items[0]="lion"
items[5]="tiger" # Appends to end
# Delete elements
unset items[2] # Remove element
unset items # Clear entire array
# Slice extraction
${items[@]:1:3} # Elements from index 1, length 3
# Content replacement
${items[@]/i/XX} # Replace 'i' with 'XX' in all elements
# Iterate through array
for item in ${items[@]}
do
echo $item
done
Export Variables
#!/bin/bash
#
echo $myvar # Empty without declaration
myvar=100
declare -x myvar # Now accessible in child processes
Using declare -x exports the variable to the environment, making it available to subprocesses.