Linux Bash supports a powerful set of built-in string manipulation operations. While older Bourne shell scripts frequently invoked external tools like expr or awk, modern Bash provides instant Parameter Expansion with the ${} syntax that executes directly within the shell memory without launching child subshells.
The fastest and cleanest way to calculate the length (character count) of a string variable is ${#string}:
#!/bin/bash
# Note: Never put spaces around '=' during variable assignment!
str="Veewom Linux Programming"
# Pure Bash parameter expansion (Recommended - very fast)
len=${#str}
echo "Length using \${#str}: $len"
# Legacy UNIX method using expr (Requires quotes if string contains spaces)
len_expr=$(expr length "$str")
echo "Length using expr: $len_expr"
Extracting a specific slice of a string is done using ${string:offset:length}, where offset is the 0-based starting index:
Syntax |
Description |
Example Output |
|---|---|---|
|
Extracts from index offset to the end of string. |
|
|
Extracts length characters starting from index offset. |
|
|
Extracts the last N characters from the end (notice leading space!). |
|
Bash allows pattern-based text replacement without running sed:
#!/bin/bash
msg="I love unix. unix is fast and unix is robust."
# Replace first match: ${var/pattern/replacement}
echo "${msg/unix/Linux}"
# Output: I love Linux. unix is fast and unix is robust.
# Replace ALL matches globally: ${var//pattern/replacement}
echo "${msg//unix/Linux}"
# Output: I love Linux. Linux is fast and Linux is robust.
# Replace only if match occurs at the BEGINNING: ${var/#pattern/replacement}
path="/var/log/syslog"
echo "${path/#\/var/\/tmp}"
# Output: /tmp/log/syslog
# Replace only if match occurs at the END: ${var/%pattern/replacement}
file="report.txt"
echo "${file/%.txt/.pdf}"
# Output: report.pdf
System administrators and shell programmers constantly extract filenames or directories from path strings using prefix/suffix removal:
Pattern |
Action |
Example on |
|---|---|---|
|
Remove shortest match from start (prefix). |
|
|
Remove longest match from start (basename extraction). |
|
|
Remove shortest match from end (strip file extension). |
|
|
Remove longest match from end (dirname extraction). |
|
#!/bin/bash
company="Veewom Tech"
# Convert to all UPPERCASE with ^^
echo "${company^^}" # VEEWOM TECH
# Convert to all lowercase with ,,
echo "${company,,}" # veewom tech
# Capitalize only the first character with ^
lang="bash"
echo "${lang^}" # Bash
Operator |
Condition Checked |
Example |
|---|---|---|
| Strings are equal |
|
| Strings are NOT equal |
|
| String is NULL or length is 0 (Empty) |
|
| String is NOT null (Has characters) |
|
| Matches regular expression (in |
|
Problem 1: Write a shell script to reverse a string and check whether it is a palindrome.
#!/bin/bash
# palindrome.sh: Check if string is palindrome
read -p "Enter a word or string: " input
len=${#input}
reverse=""
# Loop backwards through characters
for (( i=$len-1; i>=0; i-- )); do
reverse="$reverse${input:$i:1}"
done
echo "Original string : $input"
echo "Reversed string : $reverse"
if [ "$input" = "$reverse" ]; then
echo "Result: '$input' IS a Palindrome!"
else
echo "Result: '$input' is NOT a Palindrome."
fi
Problem 2: Extract the filename without extension and directory path from a full path string:
#!/bin/bash
# path_parser.sh
full_path="/var/www/html/veewom/index.htm"
filename="${full_path##*/}" # index.htm
basename="${filename%.*}" # index
extension="${full_path##*.}" # htm
directory="${full_path%/*}" # /var/www/html/veewom
echo "Full Path : $full_path"
echo "Directory : $directory"
echo "File Name : $filename"
echo "Base Name : $basename"
echo "Extension : $extension"
${#variable_name}. For instance, if name="Linux", ${#name} evaluates directly to 5 without spawning subshell processes.
${string//search_term/replace_term}. A single slash replaces only the first occurrence.
-z test operator: if [ -z "$str" ]; then echo "String is empty"; fi. Always wrap the variable in double quotes to prevent syntax errors when the variable is unset.
# removes the shortest matching pattern, whereas double ## removes the longest matching pattern.
Advance to compiled C system programming and process creation in Class 25: Process Management & System Calls.
Continue to Class 25: Process Management & System Calls → Previous: ← Command Line | Full Syllabus