1#!/usr/bin/env bash
2set -euo pipefail
3
4# String Operations with Parameter Expansion
5# Demonstrates various string manipulation techniques using bash parameter expansion
6
7echo "=== Parameter Expansion String Operations ==="
8echo
9
10# 1. Extract filename, extension, directory from a path
11echo "1. Path Component Extraction"
12echo "----------------------------"
13filepath="/home/user/documents/report.tar.gz"
14echo "Full path: $filepath"
15echo
16
17# Remove directory path (shortest match from left)
18filename="${filepath##*/}"
19echo "Filename: $filename"
20
21# Extract directory (longest match from right)
22directory="${filepath%/*}"
23echo "Directory: $directory"
24
25# Extract basename (remove extension)
26basename="${filename%%.*}"
27echo "Basename: $basename"
28
29# Extract extension (remove everything before last dot)
30extension="${filename##*.}"
31echo "Extension: $extension"
32
33# Extract full extension (.tar.gz)
34full_extension="${filename#*.}"
35echo "Full extension: $full_extension"
36
37echo
38echo
39
40# 2. Batch rename files using parameter expansion
41echo "2. Batch Rename Simulation"
42echo "--------------------------"
43files=("photo_2023.jpg" "photo_2024.jpg" "photo_2025.png")
44
45echo "Original files:"
46printf " %s\n" "${files[@]}"
47echo
48
49echo "Renamed files (photo -> image):"
50for file in "${files[@]}"; do
51 new_name="${file/photo/image}"
52 echo " $file -> $new_name"
53done
54
55echo
56echo "Change all .jpg to .jpeg:"
57for file in "${files[@]}"; do
58 new_name="${file%.jpg}.jpeg"
59 # Only show if it actually changed
60 if [[ "$new_name" != "$file" ]]; then
61 echo " $file -> $new_name"
62 fi
63done
64
65echo
66echo
67
68# 3. Config value parsing (key=value format)
69echo "3. Config Value Parsing"
70echo "-----------------------"
71config_lines=(
72 "database_host=localhost"
73 "database_port=5432"
74 "database_name=myapp"
75 "# This is a comment"
76 "max_connections=100"
77)
78
79declare -A config
80for line in "${config_lines[@]}"; do
81 # Skip comments and empty lines
82 [[ "$line" =~ ^#.*$ ]] && continue
83 [[ -z "$line" ]] && continue
84
85 # Extract key and value
86 key="${line%%=*}"
87 value="${line#*=}"
88 config["$key"]="$value"
89 echo " $key = $value"
90done
91
92echo
93echo "Access config values:"
94echo " Database: ${config[database_name]} at ${config[database_host]}:${config[database_port]}"
95
96echo
97echo
98
99# 4. URL parsing (protocol, host, path)
100echo "4. URL Parsing"
101echo "--------------"
102url="https://api.example.com:8443/v1/users?page=1"
103echo "URL: $url"
104echo
105
106# Extract protocol
107protocol="${url%%://*}"
108echo "Protocol: $protocol"
109
110# Remove protocol to get the rest
111rest="${url#*://}"
112
113# Extract host:port and path
114host_port="${rest%%/*}"
115path="${rest#*/}"
116
117# Separate host and port
118if [[ "$host_port" == *:* ]]; then
119 host="${host_port%:*}"
120 port="${host_port#*:}"
121else
122 host="$host_port"
123 port=""
124fi
125
126echo "Host: $host"
127echo "Port: ${port:-default}"
128echo "Path: /$path"
129
130# Extract query parameters
131if [[ "$path" == *\?* ]]; then
132 query="${path#*\?}"
133 path="${path%%\?*}"
134 echo "Path (no query): /$path"
135 echo "Query string: $query"
136fi
137
138echo
139echo
140
141# 5. Default values and substitution
142echo "5. Default Values and Substitution"
143echo "-----------------------------------"
144unset optional_var
145required_var="I exist"
146
147echo "Use default if unset: ${optional_var:-default_value}"
148echo "Use default if unset or empty: ${optional_var-default_value}"
149echo "Variable doesn't change: optional_var=${optional_var:-}"
150
151# Assign default if unset
152echo "Assign default: ${optional_var:=assigned_default}"
153echo "Now optional_var=$optional_var"
154
155echo
156echo "Use alternate value if set:"
157echo " required_var is set: ${required_var:+yes, it is set}"
158echo " optional_var is set: ${optional_var:+yes, it is set}"
159
160echo
161echo
162
163# 6. String length and substring
164echo "6. String Length and Substring"
165echo "------------------------------"
166text="Hello, World!"
167echo "Text: $text"
168echo "Length: ${#text}"
169echo "Substring (0-5): ${text:0:5}"
170echo "Substring (7-5): ${text:7:5}"
171echo "Last 6 chars: ${text: -6}"
172
173echo
174echo
175
176# 7. Case conversion (bash 4.0+)
177echo "7. Case Conversion"
178echo "------------------"
179mixed="Hello World"
180echo "Original: $mixed"
181echo "Lowercase: ${mixed,,}"
182echo "Uppercase: ${mixed^^}"
183echo "First char uppercase: ${mixed^}"
184echo "First char of each word uppercase: ${mixed^^[hw]}"
185
186echo
187echo "=== Demo Complete ==="