0
0
Bash Scriptingscripting~15 mins

String replacement (${var/old/new}) in Bash Scripting - Deep Dive

Choose your learning style9 modes available
Overview - String replacement (${var/old/new})
What is it?
String replacement using ${var/old/new} is a way to change parts of a text stored in a variable in bash scripts. It looks for a specific pattern (old) inside the variable's value and replaces it with another text (new). This happens directly in the script without needing extra commands. It helps modify text quickly and simply.
Why it matters
Without this feature, changing parts of text in scripts would require calling external tools like sed or awk, which slows down scripts and makes them more complex. String replacement makes scripts faster and easier to write, especially when you need to update or clean up text data on the fly.
Where it fits
Before learning this, you should know how to create and use variables in bash. After mastering string replacement, you can explore more advanced text processing tools like sed, awk, or regular expressions for complex patterns.
Mental Model
Core Idea
You can directly swap parts of a variable's text by specifying what to find and what to replace it with inside ${var/old/new}.
Think of it like...
It's like using the find-and-replace feature in a text editor but doing it instantly inside your script on a stored word or sentence.
Variable content: "hello world"
Replace 'world' with 'bash':
${var/world/bash} → "hello bash"

Flow:
[variable text] --find 'old'--> [replace with 'new'] --> [new text]
Build-Up - 7 Steps
1
FoundationUnderstanding Bash Variables
šŸ¤”
Concept: Learn what a variable is and how to store text in it.
In bash, you can store text in a variable like this: name="world" You can then use it by writing: echo "Hello $name" This will print: Hello world
Result
Hello world
Knowing how to store and use variables is the base for any text manipulation in bash.
2
FoundationBasic String Replacement Syntax
šŸ¤”
Concept: Introduce the ${var/old/new} syntax for replacing text inside variables.
If you have a variable: text="hello world" You can replace 'world' with 'bash' by writing: echo "${text/world/bash}" This prints: hello bash
Result
hello bash
This shows how bash can change parts of a variable's text without extra commands.
3
IntermediateReplacing Only First Occurrence
šŸ¤”Before reading on: do you think ${var/old/new} replaces all or just the first match? Commit to your answer.
Concept: Understand that ${var/old/new} replaces only the first match of 'old' in the variable.
Given: text="one two one two" Using: echo "${text/one/ONE}" Output will be: ONE two one two Only the first 'one' is replaced.
Result
ONE two one two
Knowing this prevents surprises when you expect all matches to change but only the first does.
4
IntermediateReplacing All Occurrences with Double Slash
šŸ¤”Before reading on: how do you think you replace all matches, not just the first? Guess the syntax.
Concept: Learn that using double slashes ${var//old/new} replaces every match in the variable.
Given: text="one two one two" Using: echo "${text//one/ONE}" Output will be: ONE two ONE two All 'one' words are replaced.
Result
ONE two ONE two
This shows how to fully clean or update text by replacing every matching part.
5
IntermediateUsing Patterns in Replacement
šŸ¤”
Concept: You can use simple patterns (globs) in the 'old' part to match text, not just exact words.
Example: text="file1.txt file2.txt file3.log" Replace all '.txt' with '.bak': echo "${text//*.txt/.bak}" Output: file1.bak file2.bak file3.log Note: This replaces the whole match of '*.txt' with '.bak'.
Result
file1.bak file2.bak file3.log
Patterns let you replace groups of similar text, but be careful as it replaces the whole matched part.
6
AdvancedReplacing Prefix or Suffix Only
šŸ¤”Before reading on: can you replace only the start or end of a string using this syntax? Guess how.
Concept: Learn special forms ${var/#old/new} to replace only if 'old' is at the start, and ${var/%old/new} if at the end.
Given: text="hello world" Replace 'hello' only if at start: echo "${text/#hello/hi}" Output: hi world Replace 'world' only if at end: echo "${text/%world/bash}" Output: hello bash
Result
hi world hello bash
This lets you target replacements precisely at string edges, useful for formatting or cleaning.
7
ExpertLimitations and Surprises of String Replacement
šŸ¤”Before reading on: do you think this replacement supports full regular expressions? Commit your guess.
Concept: Understand that bash string replacement uses simple glob patterns, not full regex, and replacements are literal text.
Example: text="file123.txt" Trying regex like digits: echo "${text//[0-9]/X}" Output: fileXXX.txt This works because glob treats [0-9] as a set, but complex regex like \d+ won't work. Also, replacement text is literal; no backreferences or special symbols.
Result
fileXXX.txt
Knowing these limits avoids confusion and helps decide when to use external tools like sed for complex patterns.
Under the Hood
Bash performs string replacement during variable expansion by scanning the variable's value for the pattern 'old' using simple glob matching. It then constructs a new string by replacing the matched part(s) with 'new'. This happens entirely in the shell process without spawning external commands, making it fast. The shell treats the replacement text literally, not interpreting special characters or regex.
Why designed this way?
This feature was designed to provide a lightweight, fast way to do common text substitutions without overhead. Using simple glob patterns instead of full regex keeps the implementation simple and efficient inside the shell. For complex needs, external tools exist, so bash focuses on speed and simplicity for everyday scripting.
Variable value: [ hello world world ]

Pattern match:       [      world      ]

Replacement:         [      bash       ]

Result:              [ hello bash world ]

Flow:
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ Variable text │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
       │
       ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ Pattern match │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
       │
       ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ Replace text  │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
       │
       ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ New variable  │
│    value      │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
Myth Busters - 4 Common Misconceptions
Quick: Does ${var/old/new} replace all matches or just the first? Commit to your answer.
Common Belief:It replaces all occurrences of 'old' in the variable.
Tap to reveal reality
Reality:It replaces only the first occurrence. To replace all, you must use ${var//old/new}.
Why it matters:Expecting all matches to change but only one does can cause bugs in scripts that process multiple items.
Quick: Can you use full regular expressions inside ${var/old/new}? Commit to yes or no.
Common Belief:You can use full regex patterns for matching text.
Tap to reveal reality
Reality:Only simple glob patterns are supported, not full regex. Complex patterns require external tools.
Why it matters:Trying to use regex syntax here leads to unexpected results and confusion.
Quick: Does the replacement part support backreferences like \1? Commit your guess.
Common Belief:You can use backreferences in the replacement text to reuse matched parts.
Tap to reveal reality
Reality:Replacement text is literal; backreferences are not supported in bash string replacement.
Why it matters:Scripts expecting backreferences will fail silently or produce wrong output.
Quick: Does ${var/#old/new} replace 'old' anywhere in the string? Commit your answer.
Common Belief:${var/#old/new} replaces 'old' anywhere in the variable's text.
Tap to reveal reality
Reality:It replaces 'old' only if it appears at the start of the string.
Why it matters:Misunderstanding this causes replacements to silently fail when 'old' is not at the start.
Expert Zone
1
Using string replacement inside parameter expansions can interact subtly with quoting and word splitting, so always quote expansions to avoid surprises.
2
When chaining multiple replacements, the order matters because each replacement works on the result of the previous one, which can cause unexpected results if not planned.
3
In some bash versions, string replacement does not work on arrays directly; you must loop over elements or use other methods.
When NOT to use
Avoid using bash string replacement for complex pattern matching or when you need regex features like capturing groups or lookaheads. Instead, use tools like sed, awk, or perl for those cases.
Production Patterns
In real scripts, this feature is often used for quick filename or path modifications, simple data cleaning, or toggling flags in strings. Experts combine it with conditionals and loops for efficient text processing without external calls.
Connections
sed stream editor
More powerful external tool for text replacement using full regular expressions.
Knowing bash string replacement helps understand sed's simpler use cases and when to switch to it for complex patterns.
Text find-and-replace in editors
Same basic idea of swapping text parts, but interactive and visual.
Understanding this connection helps grasp how automated scripts mimic manual editing tasks.
DNA sequence mutation in biology
Both involve replacing specific patterns in a long string to change meaning or function.
Seeing string replacement as a mutation process helps appreciate its power and risks in changing data precisely.
Common Pitfalls
#1Replacing all matches but using single slash syntax.
Wrong approach:text="one two one two" echo "${text/one/ONE}"
Correct approach:text="one two one two" echo "${text//one/ONE}"
Root cause:Confusing single slash (first match only) with double slash (all matches).
#2Expecting regex features like + or \d to work.
Wrong approach:text="file123.txt" echo "${text//\d/X}"
Correct approach:Use sed for regex: echo "$text" | sed 's/[0-9]/X/g'
Root cause:Misunderstanding that bash string replacement uses glob patterns, not regex.
#3Trying to use backreferences in replacement text.
Wrong approach:text="abc123" echo "${text//[0-9]/\1}"
Correct approach:Use sed for backreferences: echo "$text" | sed 's/\([0-9]\)/\1/g'
Root cause:Assuming replacement supports regex features which it does not.
Key Takeaways
Bash string replacement ${var/old/new} lets you quickly change parts of a variable's text without external tools.
Single slash replaces only the first match; double slash replaces all matches in the variable.
Only simple glob patterns are supported for matching, not full regular expressions.
Replacement text is literal; no backreferences or special regex features are available.
Special forms ${var/#old/new} and ${var/%old/new} let you replace only at the start or end of the string.