1#!/usr/bin/env bash
2set -euo pipefail
3
4# Associative Arrays Demonstrations
5# Shows practical uses of associative arrays (hash maps/dictionaries)
6
7# --- Word Frequency Counter ---
8word_frequency() {
9 echo "=== Word Frequency Counter ==="
10 echo
11
12 local input_file="${1:-}"
13 declare -A word_count
14
15 # Read from file or stdin
16 local text
17 if [[ -n "$input_file" && -f "$input_file" ]]; then
18 text=$(cat "$input_file")
19 echo "Reading from file: $input_file"
20 else
21 if [[ -t 0 ]]; then
22 # Terminal input, use sample text
23 text="the quick brown fox jumps over the lazy dog the fox is quick"
24 echo "Using sample text:"
25 echo "\"$text\""
26 else
27 # Pipe/redirect input
28 text=$(cat)
29 echo "Reading from stdin"
30 fi
31 fi
32
33 echo
34
35 # Convert to lowercase and split into words
36 for word in $text; do
37 # Remove punctuation and convert to lowercase
38 word=$(echo "$word" | tr -d '.,!?;:' | tr '[:upper:]' '[:lower:]')
39 [[ -z "$word" ]] && continue
40
41 # Increment count
42 ((word_count[$word]++)) || word_count[$word]=1
43 done
44
45 # Display results sorted by frequency
46 echo "Word frequencies:"
47 for word in "${!word_count[@]}"; do
48 echo "${word_count[$word]} $word"
49 done | sort -rn | awk '{printf " %-15s %d\n", $2, $1}'
50
51 echo
52}
53
54# --- Config File Loader ---
55load_config() {
56 echo "=== Config File Loader ==="
57 echo
58
59 declare -gA config
60
61 # Create a sample config file
62 local config_file="/tmp/sample_config.ini"
63 cat > "$config_file" << 'EOF'
64# Database Configuration
65database.host=localhost
66database.port=5432
67database.name=myapp
68database.user=admin
69
70# Application Settings
71app.name=MyApplication
72app.version=1.2.3
73app.debug=true
74app.max_connections=100
75
76# Cache Settings
77cache.enabled=true
78cache.ttl=3600
79EOF
80
81 echo "Loading config from: $config_file"
82 echo
83
84 # Parse config file
85 while IFS='=' read -r key value; do
86 # Skip comments and empty lines
87 [[ "$key" =~ ^#.*$ ]] && continue
88 [[ -z "$key" ]] && continue
89
90 # Trim whitespace
91 key=$(echo "$key" | xargs)
92 value=$(echo "$value" | xargs)
93
94 config["$key"]="$value"
95 done < "$config_file"
96
97 # Display loaded config
98 echo "Loaded configuration:"
99 for key in "${!config[@]}"; do
100 echo " $key = ${config[$key]}"
101 done | sort
102
103 echo
104 echo "Accessing specific values:"
105 echo " Database: ${config[database.name]} at ${config[database.host]}:${config[database.port]}"
106 echo " App: ${config[app.name]} v${config[app.version]}"
107 echo " Debug mode: ${config[app.debug]}"
108
109 echo
110
111 # Cleanup
112 rm -f "$config_file"
113}
114
115# --- Simple Phonebook ---
116phonebook() {
117 echo "=== Simple Phonebook ==="
118 echo
119
120 declare -A phonebook
121
122 # Add entries
123 add_contact() {
124 local name="$1"
125 local number="$2"
126 phonebook["$name"]="$number"
127 echo " ✓ Added: $name -> $number"
128 }
129
130 # Lookup entry
131 lookup_contact() {
132 local name="$1"
133 if [[ -n "${phonebook[$name]+x}" ]]; then
134 echo " $name: ${phonebook[$name]}"
135 else
136 echo " ✗ Contact '$name' not found"
137 fi
138 }
139
140 # Delete entry
141 delete_contact() {
142 local name="$1"
143 if [[ -n "${phonebook[$name]+x}" ]]; then
144 unset 'phonebook[$name]'
145 echo " ✓ Deleted: $name"
146 else
147 echo " ✗ Contact '$name' not found"
148 fi
149 }
150
151 # List all entries
152 list_contacts() {
153 if [[ ${#phonebook[@]} -eq 0 ]]; then
154 echo " (phonebook is empty)"
155 return
156 fi
157
158 echo " Phonebook entries:"
159 for name in "${!phonebook[@]}"; do
160 printf " %-20s %s\n" "$name" "${phonebook[$name]}"
161 done | sort
162 }
163
164 # Demo operations
165 echo "Adding contacts..."
166 add_contact "Alice Smith" "555-0101"
167 add_contact "Bob Jones" "555-0102"
168 add_contact "Charlie Brown" "555-0103"
169 add_contact "Diana Prince" "555-0104"
170
171 echo
172 list_contacts
173
174 echo
175 echo "Looking up contacts..."
176 lookup_contact "Alice Smith"
177 lookup_contact "Bob Jones"
178 lookup_contact "Eve (Unknown)"
179
180 echo
181 echo "Deleting a contact..."
182 delete_contact "Bob Jones"
183
184 echo
185 list_contacts
186
187 echo
188 echo "Total contacts: ${#phonebook[@]}"
189
190 echo
191}
192
193# --- Multi-level Dictionary ---
194nested_example() {
195 echo "=== Nested Data Structure (Simulated) ==="
196 echo
197
198 declare -A user_data
199
200 # Store structured data using key prefixes
201 user_data["user1.name"]="Alice"
202 user_data["user1.email"]="alice@example.com"
203 user_data["user1.age"]="30"
204
205 user_data["user2.name"]="Bob"
206 user_data["user2.email"]="bob@example.com"
207 user_data["user2.age"]="25"
208
209 user_data["user3.name"]="Charlie"
210 user_data["user3.email"]="charlie@example.com"
211 user_data["user3.age"]="35"
212
213 echo "Stored user data:"
214 for key in "${!user_data[@]}"; do
215 echo " $key = ${user_data[$key]}"
216 done | sort
217
218 echo
219 echo "Query users by prefix:"
220
221 query_user() {
222 local user_id="$1"
223 echo " $user_id:"
224 for key in "${!user_data[@]}"; do
225 if [[ "$key" == "$user_id."* ]]; then
226 local field="${key#*.}"
227 printf " %-10s %s\n" "$field" "${user_data[$key]}"
228 fi
229 done
230 }
231
232 query_user "user1"
233 echo
234 query_user "user2"
235
236 echo
237}
238
239# --- Main execution ---
240main() {
241 word_frequency
242 echo
243 echo "----------------------------------------"
244 echo
245
246 load_config
247 echo "----------------------------------------"
248 echo
249
250 phonebook
251 echo "----------------------------------------"
252 echo
253
254 nested_example
255
256 echo "=== All Demos Complete ==="
257}
258
259main "$@"