String suffix removal (${var%pattern}) in Bash Scripting - Time & Space Complexity
We want to understand how long it takes to remove a suffix from a string using bash's ${var%pattern} syntax.
Specifically, how does the time needed change as the string or pattern size grows?
Analyze the time complexity of the following code snippet.
string="filename_backup_2024.txt"
pattern="*.txt"
result=${string%$pattern}
echo "$result"
This code removes the shortest suffix matching the pattern from the string.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Matching the pattern against the string suffix.
- How many times: The shell checks suffixes from the end of the string, moving backward until a match is found.
As the string length grows, the shell tries more suffixes to find a match.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to 10 suffix checks |
| 100 | Up to 100 suffix checks |
| 1000 | Up to 1000 suffix checks |
Pattern observation: The number of checks grows roughly in direct proportion to the string length.
Time Complexity: O(n)
This means the time to remove the suffix grows linearly with the string length.
[X] Wrong: "The suffix removal happens instantly no matter how long the string is."
[OK] Correct: The shell must check suffixes step by step, so longer strings take more time.
Understanding how string operations scale helps you write efficient scripts and explain your reasoning clearly in interviews.
"What if we used the longest suffix removal syntax ${var%%pattern} instead? How would the time complexity change?"
Practice
${filename%.txt} do to the variable filename?Solution
Step 1: Understand the % operator in Bash
The single % operator removes the shortest matching suffix pattern from the variable's value.Step 2: Apply to the pattern '.txt'
It removes '.txt' only if it appears at the end of the string, trimming that suffix.Final Answer:
Removes the shortest suffix matching '.txt' from the end of filename -> Option CQuick Check:
${var%pattern} removes shortest suffix [OK]
- Confusing % with prefix removal operators
- Using %% instead of %
- Thinking it removes prefix instead of suffix
file in Bash?Solution
Step 1: Identify suffix removal syntax
To remove the shortest suffix matching a pattern, use single % with the pattern including the dot: %.logStep 2: Check each option
A uses %% which removes longest suffix, C uses # which removes prefix, D misses the dot before 'log'. Only B is correct syntax.Final Answer:
${file%.log} -> Option BQuick Check:
Use single % with pattern for shortest suffix removal [OK]
- Using %% instead of %
- Confusing % with # for prefix removal
- Omitting the dot in the pattern
filename="report.final.txt"
echo ${filename%.txt}What is the output?
Solution
Step 1: Understand the variable value
The variable filename contains 'report.final.txt'.Step 2: Apply ${filename%.txt}
This removes the shortest suffix matching '.txt' from the end, leaving 'report.final'.Final Answer:
report.final -> Option DQuick Check:
Suffix '.txt' removed once from end [OK]
- Removing more than '.txt' suffix
- Confusing prefix removal with suffix removal
- Expecting the full string unchanged
file="archive.tar.gz"
echo ${file%*.gz}It outputs
archive.tar. You want to remove the entire suffix .tar.gz. What is the fix?Solution
Step 1: Understand why ${file%*.gz} removes only '.gz'
Single % removes shortest suffix matching *.gz pattern, so it matches '.gz' (with * matching empty).Step 2: Use %% to remove longest suffix
Double %% removes longest matching suffix, so ${file%%*.gz} removes entire '.tar.gz'.Final Answer:
Use ${file%%*.gz} to remove the longest matching suffix -> Option AQuick Check:
%% removes longest suffix, % removes shortest [OK]
- Using single % when longest suffix removal needed
- Confusing prefix removal (#) with suffix removal (%)
- Trying to remove partial suffix only
files=("data1.csv" "data2.csv" "notes.txt" "summary.csv")You want to remove the '.csv' suffix only from files that end with '.csv' using Bash parameter expansion. Which command correctly prints the filenames with '.csv' removed where applicable?
Solution
Step 1: Understand the goal
Remove '.csv' suffix only if it exists, leave other filenames unchanged.Step 2: Check each option's effect
A uses single % with '.csv' pattern, removing suffix if present. B uses %%csv missing the dot, incorrect. C misses the dot, incorrect. D uses # which removes prefix, wrong direction.Step 3: Choose best option
for f in "${files[@]}"; do echo ${f%.csv}; done is correct and simplest for shortest suffix removal of '.csv'.Final Answer:
for f in "${files[@]}"; do echo ${f%.csv}; done -> Option AQuick Check:
Use ${var%.csv} to remove '.csv' suffix if present [OK]
- Using prefix removal (#) instead of suffix removal (%)
- Omitting the dot in suffix pattern
- Using %% unnecessarily when % suffices
Ready to prove it?
Pass the test and this pattern moves unknown
