0
0
Bash Scriptingscripting~15 mins

String suffix removal (${var%pattern}) in Bash Scripting - Deep Dive

Choose your learning style9 modes available
Overview - String suffix removal (${var%pattern})
What is it?
String suffix removal using ${var%pattern} is a way in bash scripting to delete the shortest matching part of a pattern from the end of a string stored in a variable. It helps you quickly cut off unwanted endings without changing the original string. This is done directly in the shell without needing extra commands.
Why it matters
Without this feature, removing parts from the end of strings would require more complex commands or external tools, making scripts slower and harder to read. It simplifies text processing tasks like trimming file extensions or paths, which are common in automation and scripting. This makes scripts cleaner, faster, and easier to maintain.
Where it fits
Before learning this, you should understand basic bash variables and string handling. After mastering suffix removal, you can learn prefix removal (${var#pattern}), substring extraction, and advanced pattern matching in bash scripting.
Mental Model
Core Idea
You tell bash to cut off the shortest matching ending pattern from a string variable using ${var%pattern}.
Think of it like...
Imagine you have a ribbon with a tag at the end, and you want to cut off just the tag without touching the rest. The pattern is like the shape of the tag you want to remove from the ribbon's end.
String:  [HelloWorld.txt]
Pattern:          [*.txt]
Result:  [HelloWorld]
Build-Up - 7 Steps
1
FoundationUnderstanding Bash Variables
🤔
Concept: Learn what bash variables are and how to store strings in them.
In bash, you can store text in variables like this: filename="HelloWorld.txt" echo $filename This prints the string stored in filename.
Result
HelloWorld.txt
Knowing how to store and access strings in variables is the base for manipulating them with suffix removal.
2
FoundationBasic String Patterns in Bash
🤔
Concept: Learn how bash uses patterns with wildcards like * to match parts of strings.
The * wildcard matches any number of characters. For example: pattern="*.txt" matches any string ending with .txt You can use this in commands like: ls *.txt which lists all files ending with .txt.
Result
Lists files ending with .txt in the current directory
Understanding patterns with * is essential because suffix removal uses these patterns to decide what to cut off.
3
IntermediateUsing ${var%pattern} for Suffix Removal
🤔
Concept: Learn how to remove the shortest matching suffix pattern from a variable's value.
Given a variable: filename="report.pdf" You can remove the shortest suffix matching .pdf like this: base=${filename%.pdf} echo $base This prints 'report' by cutting off '.pdf' from the end.
Result
report
This shows how ${var%pattern} directly trims endings without extra commands, making scripts simpler.
4
IntermediateDifference Between % and %% Operators
🤔Before reading on: do you think ${var%pattern} and ${var%%pattern} remove the same part or different parts of the suffix? Commit to your answer.
Concept: Learn the difference between removing the shortest vs longest matching suffix.
Using one % removes the shortest match from the end: filename="archive.tar.gz" ${filename%.gz} # removes '.gz' only Using two %% removes the longest match: ${filename%%.gz} # tries to remove longest match ending with '.gz', but here same as % More useful example: filename="file.backup.tar.gz" ${filename%.tar.gz} # removes '.tar.gz' ${filename%%.gz} # removes '.backup.tar.gz' because it matches longest suffix ending with '.gz'
Result
Short % removes shortest suffix; double %% removes longest suffix
Knowing shortest vs longest removal helps avoid bugs when suffixes have multiple parts.
5
IntermediateCombining Suffix Removal with Other String Operations
🤔Before reading on: do you think you can chain suffix removal with prefix removal in one expression? Commit to your answer.
Concept: Learn how to combine suffix removal with prefix removal for complex string trimming.
You can combine suffix and prefix removal like this: filepath="/home/user/document.txt" filename=${filepath##*/} # removes longest prefix ending with '/', result: 'document.txt' base=${filename%.txt} # removes shortest suffix '.txt', result: 'document' echo $base This extracts the filename without path and extension.
Result
document
Combining these operations lets you extract or clean parts of strings efficiently in scripts.
6
AdvancedUsing Patterns with Wildcards in Suffix Removal
🤔Before reading on: do you think you can use wildcards like * inside the pattern for suffix removal? Commit to your answer.
Concept: Learn how to use wildcards in the pattern to remove variable suffixes.
You can use * to match variable parts: filename="backup_2023_06_01.tar.gz" base=${filename%_*.tar.gz} echo $base This removes the shortest suffix matching '_*.tar.gz', so it cuts off '_06_01.tar.gz', leaving 'backup_2023'.
Result
backup_2023
Using wildcards in patterns makes suffix removal flexible for many filename or string formats.
7
ExpertPerformance and Limitations of Suffix Removal
🤔Before reading on: do you think suffix removal is slower than external commands like sed or awk? Commit to your answer.
Concept: Understand the efficiency and edge cases of suffix removal in bash.
Suffix removal is a shell builtin operation, so it is very fast compared to calling external tools. However, it only supports glob patterns, not full regular expressions. Complex patterns or multi-line strings cannot be handled. Also, if the pattern does not match, the original string is returned unchanged. Example: filename="data.csv" base=${filename%.txt} echo $base Output is 'data.csv' because '.txt' suffix not found.
Result
data.csv
Knowing these limits helps choose the right tool: suffix removal for simple patterns and speed, external tools for complex text processing.
Under the Hood
Bash performs suffix removal by matching the pattern against the end of the string stored in the variable using shell globbing rules. It scans from the right side to find the shortest (or longest with %% operator) substring that fits the pattern and removes it. This happens internally in the shell parser before the command runs, so no external process is spawned.
Why designed this way?
This feature was designed to provide fast, simple string manipulation directly in the shell without overhead. Using glob patterns instead of full regex keeps it lightweight and easy to implement. It fits the Unix philosophy of small, composable tools and avoids the cost of calling external programs for common tasks.
Variable value: [filename = "archive.tar.gz"]

Suffix removal process:

  +-----------------------------+
  | Bash shell receives ${filename%.gz} |
  +-------------+---------------+
                |
                v
  +-----------------------------+
  | Match shortest suffix '.gz' |
  +-------------+---------------+
                |
                v
  +-----------------------------+
  | Remove '.gz' from end        |
  +-------------+---------------+
                |
                v
  +-----------------------------+
  | Result: 'archive.tar'        |
  +-----------------------------+
Myth Busters - 4 Common Misconceptions
Quick: Does ${var%pattern} remove the longest matching suffix or the shortest? Commit to your answer.
Common Belief:Many think ${var%pattern} removes the longest matching suffix from the string.
Tap to reveal reality
Reality:It actually removes the shortest matching suffix. To remove the longest, you must use ${var%%pattern}.
Why it matters:Using the wrong operator can lead to unexpected string results and bugs in scripts, especially with complex suffixes.
Quick: If the pattern does not match the string's suffix, does ${var%pattern} change the string? Commit to your answer.
Common Belief:Some believe that if the pattern doesn't match, the string will be altered or truncated anyway.
Tap to reveal reality
Reality:If the pattern does not match, the original string is returned unchanged.
Why it matters:Assuming the string changes can cause logic errors or data loss in scripts.
Quick: Can ${var%pattern} use full regular expressions for pattern matching? Commit to your answer.
Common Belief:People often think the pattern supports full regular expressions like grep or sed.
Tap to reveal reality
Reality:The pattern uses shell globbing (wildcards like *, ?, []) only, not full regex.
Why it matters:Expecting regex can lead to incorrect patterns and failed string manipulations.
Quick: Does ${var%pattern} modify the original variable's value? Commit to your answer.
Common Belief:Some think that using ${var%pattern} changes the variable's stored value automatically.
Tap to reveal reality
Reality:It only returns the modified string; the original variable remains unchanged unless reassigned.
Why it matters:Not reassigning can cause confusion when the original string is still used later.
Expert Zone
1
Suffix removal patterns are matched using globbing rules, so character classes and ranges can be used for precise matching.
2
When chaining multiple string operations, the order matters because each step works on the result of the previous one.
3
In some shells, parameter expansion can be combined with default values and substring extraction for powerful one-liners.
When NOT to use
Avoid using suffix removal when you need full regular expression support or complex multi-line text processing. Instead, use tools like sed, awk, or Perl for those cases.
Production Patterns
In production scripts, suffix removal is commonly used to strip file extensions, extract base filenames, or clean up paths quickly. It is often combined with prefix removal and conditional checks to handle file processing pipelines efficiently.
Connections
Regular Expressions
Suffix removal uses simpler glob patterns, which are a subset of regular expressions.
Understanding glob patterns helps bridge to learning regular expressions for more advanced text matching.
Unix Philosophy
Suffix removal embodies the Unix philosophy of doing one simple task efficiently within the shell.
Recognizing this helps appreciate why shell builtins avoid complexity and external dependencies.
Human Language Editing
Suffix removal is like trimming suffixes from words in language to get root forms.
This connection shows how pattern-based trimming is a universal concept across computing and linguistics.
Common Pitfalls
#1Expecting ${var%pattern} to remove the longest suffix instead of the shortest.
Wrong approach:filename="file.backup.tar.gz" base=${filename%.gz} echo $base # outputs 'file.backup.tar' but user expects 'file'
Correct approach:filename="file.backup.tar.gz" base=${filename%%.gz} echo $base # outputs 'file.backup.tar' but still not 'file', correct pattern needed
Root cause:Confusing % (shortest) with %% (longest) and misunderstanding pattern matching leads to wrong results.
#2Using a pattern that does not match the suffix, expecting the string to change.
Wrong approach:filename="document.txt" base=${filename%.pdf} echo $base # outputs 'document.txt' unchanged
Correct approach:filename="document.txt" base=${filename%.txt} echo $base # outputs 'document'
Root cause:Not verifying the pattern matches the actual suffix causes no change and confusion.
#3Assuming ${var%pattern} modifies the variable without reassignment.
Wrong approach:filename="image.png" ${filename%.png} echo $filename # still 'image.png'
Correct approach:filename="image.png" filename=${filename%.png} echo $filename # now 'image'
Root cause:Not understanding parameter expansion returns a value but does not change the variable automatically.
Key Takeaways
The ${var%pattern} syntax removes the shortest matching suffix pattern from a string variable in bash.
It uses shell globbing patterns, not full regular expressions, so patterns must be crafted accordingly.
This operation is fast and built into the shell, making it ideal for simple string trimming tasks in scripts.
Understanding the difference between % and %% operators prevents common bugs in suffix removal.
Suffix removal does not change the original variable unless you explicitly assign the result back.