← Back to Bash Course | Chapter 7: String Manipulation | Lesson 3 of 10

Search & Replace

Parameter expansion lets you swap out parts of a string that match a pattern with something else, either just the first match or every match in the string.

Replacing the First Occurrence

${s/old/new} searches the string for old and replaces only the first match it finds with new, leaving any later occurrences untouched. This is the single-slash form of search-and-replace parameter expansion.

Example: Replacing the First Occurrence

bash
#!/bin/bash
text="cat sat on the cat mat"
result=${text/cat/dog}
echo "$result"

Replacing All Occurrences

${s//old/new} (with a double slash) replaces every occurrence of old throughout the string, not just the first one. This is the go-to form when you want a global find-and-replace.

Example: Replacing All Occurrences

bash
#!/bin/bash
text="cat sat on the cat mat"
result=${text//cat/dog}
echo "$result"

Anchoring to Start or End

${s/#old/new} only replaces old if it matches starting at the very beginning of the string, and ${s/%old/new} only replaces it if it matches ending at the very end of the string. This is useful for trimming or fixing a prefix/suffix without accidentally touching a matching substring in the middle.

Example: Anchoring to Start or End

bash
#!/bin/bash
filename="test_test_file"
start_replaced=${filename/#test_/demo_}
echo "Start replaced: $start_replaced"
end_replaced=${filename/%file/data}
echo "End replaced: $end_replaced"

Deleting Matches by Replacing With Nothing

Leaving out the replacement text entirely, ${s//old/}, effectively deletes every occurrence of old from the string since it's being replaced with an empty string. This is a quick way to strip out unwanted characters or substrings.

Example: Deleting Matches by Replacing With Nothing

bash
#!/bin/bash
phone="555-123-4567"
digits_only=${phone//-/}
echo "Digits only: $digits_only"
Common Mistakes
  1. Using ${s/old/new} when you meant to replace every occurrence; single-slash replaces only the *first* match, you need the double-slash ${s//old/new} for all occurrences.
  2. Assuming old in ${s/old/new} is a regular expression; it's actually a glob-style pattern (like in case or [[ == ]]), not a full regex.
  3. Forgetting that ${s/#old/new} anchors the match to the start of the string and ${s/%old/new} anchors it to the end -- without those anchors, the match can occur anywhere in the string.
Chapter Summary
  • ${s/old/new} replaces only the first occurrence of old with new.
  • ${s//old/new} replaces every occurrence of old with new.
  • ${s/#old/new} replaces old only if it matches at the very start of the string; ${s/%old/new} only if it matches at the very end.
  • The pattern side supports glob wildcards (*, ?, [...]), not full regular expression syntax.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.