Trimming, Replacing and Changing Case
backup.sh is given /home/asha/My Notes/ and should name the archive my_notes: just the last folder name, no trailing slash, underscores instead of spaces, all lowercase. Four small parameter expansions do the whole job without starting a single extra program.
The rule
#trims the front,%trims the end,/replaces inside.
The patterns are the same wildcards you use for file names: * matches anything, ? one character.
file=report.tar.gz
echo "${file#*.}" # tar.gz shortest match of *. removed from the front
echo "${file##*.}" # gz longest match removed from the front
echo "${file%.*}" # report.tar shortest match of .* removed from the end
echo "${file%%.*}" # report longest match removed from the endSingle # or % removes the shortest match; doubled removes the longest.
Replacing:
n="My Notes 2"
echo "${n/ /_}" # My_Notes 2 first match only
echo "${n// /_}" # My_Notes_2 every matchChanging case (Bash 4 and later):
echo "${n,,}" # my notes 2
echo "${n^^}" # MY NOTES 2Putting it together for backup.sh:
src="${src%/}" # /home/asha/My Notes
name="${src##*/}" # My Notes
name="${name// /_}" # My_Notes
name="${name,,}" # my_notesThe shortcut
Look at the keyboard. On a standard keyboard # (Shift-3) sits to the left of $ (Shift-4) and % (Shift-5) sits to its right. So # cuts from the left end of the value, % from the right. Doubling the mark means "grab as much as you can".
Which end?
We want to throw away the left part, up to a slash, so we need
#.
Drills
Answer fast — trust the rule.
With f=report.tar.gz, what is ${f%.*}?
With f=report.tar.gz, what is ${f##*.}?
With n="My Notes 2", what is ${n// /_}?
With f=report.tar.gz, which expansion gives report?
Which expansion turns n=Notes into notes, and what does it need?
Remember
#trims the front,%trims the end,/replaces inside.- Keyboard:
#is left of$,%is right. Doubled means longest match. - Trap: one
/replaces only the first match; case changes need Bash 4.
