Problem Statement
Explain advanced parameter expansion techniques in bash including default values, pattern substitution, substring extraction, and case modification.
Explanation
Default values: ${VAR:-default} returns default if VAR unset or empty (doesn't modify VAR), ${VAR:=default} assigns default if unset/empty (modifies VAR), ${VAR:+alternate} returns alternate if VAR set (opposite of :-), ${VAR:?error} exits with error message if unset/empty. Examples:
```bash
FILE=${1:-input.txt} # Use $1 or default
PORT=${PORT:=8080} # Set PORT to 8080 if not set
: ${DIR:=/tmp} # Idiom for setting defaults
```
String length and substrings: ${#VAR} returns length, ${VAR:offset} extracts from offset to end, ${VAR:offset:length} extracts length characters from offset, ${VAR: -5} extracts last 5 characters (note space before minus). Example: FILE="path/to/file.txt"; NAME="${FILE##*/}"; EXT="${FILE##*.}".
Pattern removal: ${VAR#pattern} removes shortest match from beginning, ${VAR##pattern} removes longest match from beginning, ${VAR%pattern} removes shortest match from end, ${VAR%%pattern} removes longest match from end. Examples:
```bash
FILE="/path/to/file.tar.gz"
DIR=${FILE%/*} # /path/to (remove filename)
NAME=${FILE##*/} # file.tar.gz (basename)
BASE=${FILE%%.*} # /path/to/file (remove all extensions)
EXT=${FILE##*.} # gz (last extension)
```
Pattern substitution: ${VAR/pattern/replacement} replaces first match, ${VAR//pattern/replacement} replaces all matches, ${VAR/#pattern/replacement} replaces at beginning only, ${VAR/%pattern/replacement} replaces at end only. Examples:
```bash
PATH="/usr/local/bin:/usr/bin"
NEW_PATH=${PATH//bin/sbin} # Replace all 'bin' with 'sbin'
STR="Hello World"
LOWER=${STR,,} # Convert to lowercase (bash 4+)
UPPER=${STR^^} # Convert to uppercase
CAPITAL=${STR^} # Capitalize first char
```
Case modification (bash 4+): ${VAR^} uppercases first character, ${VAR^^} uppercases all, ${VAR,} lowercases first, ${VAR,,} lowercases all, ${VAR~} toggles case of first, ${VAR~~} toggles all.
Indirection: ${!VAR} expands to value of variable named in VAR. Example: KEY="PATH"; echo ${!KEY} prints PATH's value. Indirect array: keys="!ARRAY[@]"; for key in ${!keys}; do echo $key; done.
Understanding parameter expansion eliminates need for external commands like basename, dirname, cut, sed for many string operations, making scripts faster and more portable.